﻿#NoEnv
#MaxMem 256
#SingleInstance Force
#InstallMouseHook
#InstallKeybdHook
SetBatchLines, -1
Process, Priority,, High
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen
SendMode,Input
SetWorkingDir %A_ScriptDir%
#Include lib\Class_SQLiteDB.ahk
#Include lib\Class_WinClipAPI.ahk
#Include lib\Class_WinClip.ahk
#include lib\Class_EasyIni.ahk
#include lib\Class_ToolTip.ahk
WinGetPos,Shell_WndX,Shell_WndY,Shell_WndW,Shell_Wnd ,ahk_class Shell_TrayWnd
OnMessage(0x201, "MoveActiveWindows")
OnMessage(0x200, "WM_MOUSEMOVE")
/*
if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
{
	MsgBox, 16, Error, 此工具最低支持Windows 7!,10
	ExitApp
}
*/

if (A_AhkVersion< 1.1.31) {
	MsgBox, 262160, Error, Autohotkey版本过低，请更换版本 1.1.31+!,10
	ExitApp
}
;=================================================================================================
;================================管理员身份检查与处理================================================
If !A_IsAdmin {
	Try
	{
		If A_IsCompiled {
			Run *RunAs "%A_ScriptFullPath%" /restart
			ExitApp
		}else{
			Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
		}
	}Catch e{
		MsgBox, 262160,Error,% e.Extra "`n以管理员身份运行失败！",15
		ExitApp
	}
}

;=================================================================================================
;================================重复进程检查与处理================================================
If A_IsCompiled {
	thisPID := DllCall("GetCurrentProcessId")
	if objCount(Processlist:=GetProcessNameList(A_ScriptName))>1
	{
		loop,% objCount(Processlist)
		{
			if (thisPID<>Processlist[A_Index,2]){
				process,Close,% Processlist[A_Index,2]
			}
		}
	}
}Else{
	DetectHiddenWindows, On
	thisPID := DllCall("GetCurrentProcessId")
	WinGet, List, List, %A_ScriptFullPath% ahk_class AutoHotkey
	Loop % List
	{ 
		WinGet, PID, PID, % "ahk_id" List%A_Index%
		If (PID != thisPID){
			Process, Close, %PID%
		}
	}
	DetectHiddenWindows, Off
}
;=================================================================================================
;==========================目录检查与编译时附加文件处理================================================
FileDelete, %A_Temp%\MousePosInfo.txt

if !FileExist(A_AppData "\RimeToolData\Tips\")
	FileCreateDir,%A_AppData%\RimeToolData\Tips
if !FileExist(A_AppData "\RimeToolData\TMP\")
	FileCreateDir,%A_AppData%\RimeToolData\TMP
if !FileExist(A_AppData "\RimeToolData\x64\")
	FileCreateDir,%A_AppData%\RimeToolData\x64
if !FileExist(A_AppData "\RimeToolData\x86\")
	FileCreateDir,%A_AppData%\RimeToolData\x86

FileInstall, Wubi_dz.txt, %A_AppData%\RimeToolData\TMP\Wubi_dz.txt , 1
FileInstall, icon\tool.ico, %A_AppData%\RimeToolData\Tips\tool.ico , 1
FileInstall, icon\98.png, %A_AppData%\RimeToolData\TMP\Wubi.png , 1
FileInstall, font\98WB-3.otf, %A_AppData%\RimeToolData\TMP\98WB-3.otf , 1

if !FileExist(A_AppData "\RimeToolData\Tips\Wubi_dz.txt")
	FileCopy,%A_AppData%\RimeToolData\TMP\Wubi_dz.txt,%A_AppData%\RimeToolData\Tips\Wubi_dz.txt
if !FileExist(A_AppData "\RimeToolData\Tips\Wubi.png")
	FileCopy,%A_AppData%\RimeToolData\TMP\Wubi.png,%A_AppData%\RimeToolData\Tips\Wubi.png
;================================加载98wb-3字体===============================
;;AddFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
;=============编译64位时注释32位的FileInstall以减小程序包体积，反之================
FileInstall, dll\SQLite3_x64.dll, %A_AppData%\RimeToolData\x64\sqlite3.dll , 1
FileInstall, dll\SQLite3_x86.dll, %A_AppData%\RimeToolData\x86\sqlite3.dll , 1
;===================================================================================================
;;==============================配置加载与检查=========================================================
default_value:={Settings:{initialState:0,BgColorStart:0xffffffff,BgColorEnd:0xffe9ebec, TextColor:0xfff4c51f, Margin:15
		, FontName: "98WB-3", FontSize:22, FontStyle:"Bold",Border:6,Round:18,BorderColor:0xff0298ef
		,IsRounded:1,IsRlk:1,BorderColorStart:0xff03030f,BorderColorEnd:0xffe9ebec,IsInsertMenu:0
		,TextColorStart:0xff000000,TextColorEnd:0xff16020e,Switch_hotkey:"!m",LightTheme:1
		,ToolTipStyle:1,IsShowMaYuanBiao:1,IsHelp:1,IsWarning:1,Transparent:230,Tip_hotkey:"!f1"}}
TipIni:=class_EasyIni(A_AppData "\RimeToolData\Tips\Settings.ini")
For Section, element In default_value
	For key, value In element
		If ((%key%:=TipIni[Section, key])="")
			%key%:=TipIni[Section, key]:=value

if (!InStr(GetFontList(),"98WB-3")&&FontName="98WB-3"){
	if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
	{
		AddFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
	}else{
		FontName:=A_AppData . "\RimeToolData\TMP\98WB-3.otf"
	}
}

TipIni.DeleteSection("Setting"),ClickTime:=A_Now
,GuiAlwaysOnTop:=0,versions:=1.48,TaskName:="五笔反查助手 (Run As Task)"
,OSVersionCaption:=GetOSVersionInfo(),TipIni.save()
;;=========================注册热键与字体处理======================================================
Try
{
	if Switch_hotkey:=Format_hotkey2(Switch_hotkey) {
		Hotkey,$%Switch_hotkey%,Toggle_rlk,On
		Gosub DeskTopTip
	}
	if Tip_hotkey:=Format_hotkey2(Tip_hotkey) {
		Hotkey,$%Tip_hotkey%,rlk_label,On
	}
	Hotkey,~LButton,ControlLButton,On
	if (A_PtrSize>4){
		Hotkey,~RButton,ControlRButton,On
	}
}Catch{
	TrayTip,Error,热键名不规范，注册出错！,,3
}
;;==============================================================================================

If !initialState {
	MsgBox, 262176, 初始化,操作说明：`n1、运行后以鼠标划选汉字会自动显示五笔编码与码元拆分。`n2、鼠标反查开关初始热键为Alt+M，具体的设置可以进托盘`n    菜单的设置窗口进行设置。`n3、如果码元显示不正常请在设置进行安装字体操作。`n4、Ctrl+鼠标滚轮单击可以置顶/取消置顶当前窗口。`n5、工具限定单次划选长度在屏幕的纵向分辨率1/3以内.
	IfMsgBox OK
		initialState:=TipIni.Settings["initialState"]:=!initialState, TipIni.save()
}
;;=======================================================================================
;;====================base64转png图标======================================================

Base64Data_close_1:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAA60lEQVRIS72W2w2DMAxFbbZA2aBdp2Kd0nVQ12k3QNkCV4nqKJQ8bioFvu17/A5MnT9O6VtrL+M4vlvYOZ8DYF3XeRiGGxFNKMSJE9GybdvTGDPHge0ATpyZ786AmV8IRMVF5Or8ROQRQwIgFtcIapBfcfWLIR6QMyxlgvqEDFCH1oB2PUAg3zIsWvNdQxN9O0wRAHGN9A2tifsS5/bAjV1KKGVfGoYkoFZnJPIwiaVtLZUL3ZVsBkgWtT3J9gARR5fx/CZ3HVNAfPp70RBxPd8ttucdu67nWkeu64MTQ7o9mQrp+ui3/Ekgth+9TCIoO3CL/wAAAABJRU5ErkJggg=="
Base64Data_close_2:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAA6klEQVRIS8WWYQ7CIAyF6Y4jHMd4Hed1jMeBHYcalkGKo7SYoPvdvq+0jzIwkz9o6VtrLyGEbYTN5ZwAzrkVAK4xxpsWksSXZXki4st7v9LCKkASN8bcUwAABA2EiNtD+EEhBUDFcwUSpCGeUwtkB3QC2ZNoc8oJtAmjBVUz0EAS4Bho7nmZaaulJxdJkKSGiCrx3SzcPeCqbMX3zNAESH2ufC7YmQVoIJKN2RblCnvz0F7G/7RIqvxz0ENDnmpTSTwtv68vmkY8r++R2N8tu6nrOrti6oNDIdOeTHqDte+xlNPdRSN/FVzsGxA6ZCi+yTw1AAAAAElFTkSuQmCC"
Base64Data_min_1:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAfUlEQVRIS2N89uzZfwYaAsZRCwiFLt2C6MDfv38bCbmGFHlmZuZ6BgYGB5gPDkhJSTmSYgAhtc+ePds/agHeUBrmQQTzHqGUgiaPkhLxBtHQt+Dp06cNJAYPWLm0tDRc3zBPReQED7qe0SAiGIoYQURQB3kK4BUOedqJ0AUAnvfBsQlTIggAAAAASUVORK5CYII="
Base64Data_min_2:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAbUlEQVRIS2PU0dH5z0BDwDhqAaHQpVsQHWBgYGgk5BoS5esZGBgcYD44cOXKFUcSDcCrXEdHZ/+oBSM5iGApgMRUhZIS8aaiYWFBA4nBA1Z+5coVuL7RjEYwBEeDiPQgIqiDPAXwCoc87UToAgC5q4phRNsrHQAAAABJRU5ErkJggg=="
Base64Data_LightTheme_1:="iVBORw0KGgoAAAANSUhEUgAAABsAAAAYCAYAAAALQIb7AAAA/UlEQVRIS83UvQrCMBAH8KR9itzRd9GHcHAQHAQHwcXJwcnFyUVwEBwEJ19C36XQDL5Cy0lKK7WkbSAf2PUu+bW9f8KZg0dKuRNC7Ie24kMNJvUsy4gxtgWAQ1+/S0w5GwA4doGuMUZEa0Q86UDnmEKIaIWI5zboBauQJQBcmiBP03RkEoK+njiOn7o6ES0Q8VrXeJUkW69zPed8LoS4qQbvWPUWMwC4h8JYFEVTJzMznYGTNP4n5iL6xl8mpZwQ0cN0gU1fObNQ4DcgIcCfNPaBRVGMbX5heYO0N+gCFZYkycsG1J4zHegN04XGK9YGvWNNMAhWg3mev20D8gGZNJv3ZJlJCwAAAABJRU5ErkJggg=="
Base64Data_LightTheme_2:="iVBORw0KGgoAAAANSUhEUgAAABsAAAAYCAYAAAALQIb7AAAAzElEQVRIS83UMQoCMRCF4X9vpoewsBAsBAvBxsrCysbKRrAQLAQrL6H38RDKEwIhbLKBZILTzrAfybxNR53aAfuhT3VDA5n9D7AFDqn5mpicDXCMgbUxOWvg1AdaYHJWwDkErTA5S+Dig8JGmSFIjT0jzQVwdT1hSpJlzYGbgBaYnBlwb4UJnNbaWdYaaqXxP7Ea0c8+2QR4ZE0XDrmdNQH9gJiDYRpT4LjwFn8vSFgxUNirBIz9Z32gGaYDhKApFoLmmA82wRz4Lg3IF9WJIy6mW67dAAAAAElFTkSuQmCC"
Base64Data_top_1:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABXElEQVRIS7WVPS8EQRyHn1+h00t8AdGKDyGCROFCTySU9FxP6QoUV0hILlEJSq2CklqpVip+MnJ32duXm9k9tpydfZ75v82Kf340Cd/2HvAk6a2K01hg+wA46YNbknplkkkEx8BRBloqmUTwACzlTl2QNBLYvgY2K/I+IhkrsL0CzAHTwIekru0LYDvSHENJqcD2FNApAYVCbiR23qKkl4LA9gzQLclvIne4bV9SZ0Rgex64Ahbq0vr7H4Fn4EvSaVjLC7K9XddxI2kr/1FesA7c1iUDl5J2kgbNdn6AYr6epFatq6KBZFfSeVIEg001JW1JIfLCExu01HQdDrpmbJGzLzMRtHOXWtlBVyXdJUeQhYfQI+mq7KDCHISFPDxSkzBYa5K+k7qoCl4heQWWJX2O6+NhkWPwjCRM6yxwL+k9NiS/gv6/9QyobLcYKJqiIAm3X1NQVPDX4AHvB+OVjBmjyGEvAAAAAElFTkSuQmCC"
Base64Data_top_2:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABQklEQVRIS7XVMS8FQRSG4ecWOr3EHxCt+BEiSBSEnkgo6dFTUqBQSEgkKkGpVVBSK9VKjUyye7Pmzt7ZtZxqM3v2e8/M+c5szz9Hr6P+Jh7xWqfTBbCNg0J4GdcpSBfAHnYroklIF8A9ZqKqByC/BVxipebcf0BygDlMYBTvOMcp1jLm6EPqACM4TgiFRi41dN40nlOAsaLS+Hwb6vbTtkKRMWASF5hqq1bkP+AJnzgMazGg6u22jCusxh/FgEXctFXGGdabDlo8QDleaHxwTTLqXNQWsoGTpjso89pA9hHyByI3aE0hO6Vrck2uvi/FQ3XVSy1V6Dxu2+ygKh6eh+2k1kGpOQhrsfiwnoTBWsBXUxfViacgL5jFxzAfV5ucEy91wrSO4w5vuSEpAeHfeoRau+WEmhxRgIQr+k8jNwedYd+CyTsZlqPZUQAAAABJRU5ErkJggg=="
Base64Data_top_3:="iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABtElEQVRIS7WVvUvDUBDA71KSDHYUBKENDrbN4KL9I0RUcLDYXRF01N2662gHdeggKBScRDu6CtZFsB+L9HUSR3VoQnvyiinJS5ovNWNy7/e7d+/uBeGfH/wNv5WSdyTE+1lmvIzjxBY0UuoeIh39gAs5ZlS9JPEFaaWEAAc2qKcktqCpKXdAsChk7ZLEErQ05ZIINsbU3SHxFbTT6nKfICshJQdEHb1rVppp9QyANgOaYyTxFDwugJx8V8seIH6Q62E6j4DyOjPrLsHzzMSUPDArHvUNwx3FINFutmuWHYK2pugDggsAmI9Es4IRakTwAIQferd3zF87BEJvR3IgwlW2YxTFRQ5BS1PWiOA6EnkYjOc51tsKNWgN9wAF+ao5ZhQiXRVRJQS0rTPzNNQOrKAoEgI41JlRiiTgwWElRLhvdY3vIds/WnCenXCpuRKVAFcyrHcTegd2ON+6/07Gd5BrDuxlEevqKUGofU4aq/k6mKG6SMxcXCRInsyEvDT3+vXm18ejQQuCW5B2Sin2AacTEt1mOkYjaEiGAv5vJcQTv3YLAgWWiEv47RcXFCj4a7DF+wY3BrgZGqEjqgAAAABJRU5ErkJggg=="

Base64Data_TrayIcon1:="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"
Base64Data_TrayIcon2:="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"

Base64Toimage(Base64Data_close_1,A_Temp "\base1.png"),handle_1:=LoadPicture(A_Temp "\base1.png")
Base64Toimage(Base64Data_close_2,A_Temp "\base2.png"),handle_2:=LoadPicture(A_Temp "\base2.png")
Base64Toimage(Base64Data_min_1,A_Temp "\base3.png"),handle_3:=LoadPicture(A_Temp "\base3.png")
Base64Toimage(Base64Data_min_2,A_Temp "\base4.png"),handle_4:=LoadPicture(A_Temp "\base4.png")
Base64Toimage(Base64Data_LightTheme_1,A_Temp "\base5.png"),handle_5:=LoadPicture(A_Temp "\base5.png")
Base64Toimage(Base64Data_LightTheme_2,A_Temp "\base6.png"),handle_6:=LoadPicture(A_Temp "\base6.png")
Base64Toimage(Base64Data_top_1,A_Temp "\base7.png"),handle_7:=LoadPicture(A_Temp "\base7.png")
Base64Toimage(Base64Data_top_2,A_Temp "\base8.png"),handle_8:=LoadPicture(A_Temp "\base8.png")
Base64Toimage(Base64Data_top_3,A_Temp "\base9.png"),handle_top:=LoadPicture(A_Temp "\base9.png")
Base64Toimage(Base64Data_TrayIcon1,A_Temp "\base10.png"),handle_TrayIcon1:=LoadPicture(A_Temp "\base10.png")
Base64Toimage(Base64Data_TrayIcon2,A_Temp "\base11.png"),handle_TrayIcon2:=LoadPicture(A_Temp "\base11.png")
FileDelete,%A_Temp%\*.png
;==========================================================================
;;=======================================================================================
marks:="""",full_command_line := RegExReplace(DllCall("GetCommandLine", "str"),marks)
example_danzi=
(Join`r`n

    缶、束、赢、戍、那、越、拳、兰、垂、击、年、臧、末、凸、凹、武、卍
    平、不、卷、甴、卸、牛、秉、万、来、载、曱、夹、聿、养、曲、半、卐

)

example_danzi:=RegExReplace(example_danzi,"^[\x00-\xff]+")
example_danzi:=RegExReplace(RegExReplace(example_danzi,"\t|" A_Space),"^","        ")
example_danzi:=RegExReplace(RegExReplace(example_danzi,"\n","`n        "),"[\x00-\xff]+$")

headerTip=
(Join`r`n
一、查看码元助记和一级简码；双击托盘图标打开五笔码元图。
二、拆分规则：取大优先、兼顾直观、能连不交、能散不连。
        1、 特殊补码：衤=pu〔衤+󰁧〕      礻=py〔礻+󰁶〕
                                飠=wv〔飠+󰅞〕      犭=qt〔犭+󰁥〕
        2、 汉字中含分离的点则取消该点的分离资格，如户、亡、义、太、勺。
        3、 与单笔划相连的，取消「分离资格」，如下、天、甪、向。
        4、 汉字标准笔划中的「󰀞」在五笔字型中，视为「󰂶」，如刁、域。
              「󰄼」则视为「󰂃」。
        5、 「牛、车」在作偏旁「牜」时末笔为「󰀞」，反之为「丨」，如载、库、犇。
        6、对于码元表已存在的单字码元如：
              「刀、九、力、七」充当末位码元时，识别码一律规定为折。
        7、带大方框和走之底的，一律规定以被包围的内部码元末笔为末笔。如国、过。
        8、五个单笔画汉字的编码规定为:
              一（GGLL）、|（HHLL）、丿（TTLL）、丶（YYLL）、乙（NNLL）
        9、末笔识别码是为了避重码的，实际录入时如果输出无重则不需要加。
三、典型例字拆解：鼠标移动至此处详细查看
%example_danzi%


)
headerTip:=RegExReplace(headerTip,"^(`r`n)+|(`r`n)+$")

headerTip2=
(Join`r`n
一、字形结构：左右型、上下型、其余皆视为杂合型。
二、末笔识别码规则（最后字根的末笔所在区）：
                  横        竖        撇        捺        折
    左右      G󰀝      H󰀢      T󰁥      Y󰁶      N󰁀
    上下      F󰀘      J󰀬      R󰁣      U󰁧      B󰀅
    杂合      D󰀌      K󰀵      E󰀏      I󰀦      V󰁫
三、词组组合规则：
    二字词：每个字全码的前两码进行顺序组合。
    三字词：前两字各取全码的第首码，末字取前两码。
    四字词：各字全码的首码进行顺序组合。
    多字词：取一二三末字词全码的首码进行顺序组合。
)
headerTip2:=RegExReplace(headerTip2,"^(`r`n)+|(`r`n)+$")

headerTip3=
(Join`r`n
一、98五笔助记与一级简码
          【横区】                      【竖区】                              【撇区】
G. 王旁青头五夫一      H. 目上卜止虎头具             T. 禾竹反文双人立
F. 土干十寸未甘雨      J. 日早两竖与虫依             R. 白斤气丘叉手提
D. 大犬戊其古石厂      K. 口中两川三个竖             E. 月用力豸毛衣臼
S. 木丁西甫一四里      L. 田甲方框四车里             W. 人八登头单人几
A. 工戈草头右框七      M. 山由贝骨下框集             Q. 金夕鸟儿犭边鱼
          【捺区】                      【折区】                         【一级简码】
Y. 言文方点谁人去      N. 已类左框心尸羽      一(G)地(F)在(D)要(S)工(A)
U. 立辛六羊病门里      B. 子耳了也乃框皮      上(H)是(J)中(K)国(L)同(M)
I. 水族三点鳖头小      V. 女刀九艮山西倒      和(T)的(R)有(E)人(W)我(Q)
O. 火业广鹿四点米      C. 又巴牛厶马失蹄      主(Y)产(U)不(I)为(O)这(P)
P. 之字宝盖补礻衤      X. 幺母贯头弓和匕      民(N)了(B)发(V)以(C)经(X)

)
headerTip3:=RegExReplace(headerTip3,"^(`r`n)+|(`r`n)+$")

;;=====================================================================================
;;===================================码元表加载与检查=====================================
if FileExist(A_AppData "\RimeToolData\Tips\EtymologyTable.txt"){
	SplitEtymologyTable(A_AppData "\RimeToolData\Tips\EtymologyTable.txt")
}

if (CountLines(EtymologyList)<25){
EtymologyList1=
(
※※※※※※※横区（G-A）※※※※※※※※
  G    󰂷󰁽󰂸󰀟󰀠󰂹󰂅󰀡󰂶󰀞󰀝
  F    󰂮󰂯󰂭󰂰󰂵󰂱󰀛󰂳󰂴󰀜󰀚󰀙󰂲󰀘
  D    󰂝󰂢󰁼󰂣󰂤󰀎󰂟󰂠󰂜󰀍󰂞󰂡󰀌
  S    󰄅󰄉󰄆󰄇󰄈󰄊
  A    󰂆󰀁󰂇󰄖󰂉󰁺󰂈󰂊󰀀󰀂󰀄󰂋󰀃󰂌
)
EtymologyList2=
(
※※※※※※※竖区（H-M）※※※※※※※
  H    󰂼󰀣󰀥󰁾󰂽󰂾󰂿󰀤󰃀󰂺󰂻󰀢
  J    󰃊󰃋󰀰󰀱󰃌󰀯󰀲󰀳󰀮󰀭󰃉󰃍󰀬
  K    󰀸󰃎󰃏󰀶󰀵
  L    󰃐󰃑󰃒󰃓󰀹󰀺󰀻󰃔󰃕󰀷󰃖󰃗
  M    󰃘󰃙󰃚󰃛󰀽󰀿󰃜󰀼󰀾󰅏
)
EtymologyList3=
(
※※※※※※※撇区(T-Q)※※※※※※※
  T    󰄌󰄍󰄎󰄐󰁿󰄏󰄋󰁥
  R    󰃽󰃾󰄂󰃿󰄄󰁤󰃼󰄁󰂀󰄀󰁣
  E    󰂧󰅘󰀐󰀑󰀗󰀒󰅎󰂨󰅆󰂦󰂩󰀓󰅝󰂥󰀔󰀕󰂪󰂬󰀖󰂫󰀏
  W    󰄤󰄥󰄦󰁯󰅄󰅈󰅉󰄧󰁰󰄨󰁱
  Q    󰃴󰃶󰃵󰃷󰃻󰁚󰁛󰁜󰁞󰁟󰁠󰁡󰁢󰃸󰃹󰁝󰃺
)
EtymologyList4=
(
※※※※※※※捺区（Y-P）※※※※※※※
  Y    󰄳󰄴󰄵󰄸󰄷󰄹󰅍󰀴󰁷󰁸󰄶󰂃󰄲󰄼󰁶
  U    󰄓󰄔󰄘󰁨󰄑󰄒󰄕󰄿󰁩󰁦󰄜󰄝󰄛󰁪󰄗󰄙󰄚󰅌󰁧
  I    󰃁󰀨󰀪󰀧󰅇󰅊󰃇󰃈󰀩󰃃󰃄󰃆󰀫󰃅󰃂󰀦
  O    󰃩󰃪󰁙󰃫󰃨󰁘󰁖󰁗󰃬
  P    󰃮󰃭󰅂󰃲󰃰󰃳󰃯󰃱
)
EtymologyList5=
(
※※※※※※※折区(N-X)※※※※※※※
  N    󰁁󰁂󰁃󰁄󰃞󰃟󰃠󰃡󰃢󰃥󰅋󰁅󰃣󰃤󰁆󰃧󰁇󰁈󰁉󰁊
        󰁋󰁌󰁍󰁎󰁏󰁐󰁒󰁓󰁔󰁕󰂁󰂂󰂄󰃝󰃦󰄃󰄺󰄻󰁑󰁀
  B    󰂍󰂎󰂏󰂒󰀆󰂖󰂗󰀇󰂑󰁹󰂓󰂔󰀈󰂕󰂐󰄽󰀅
  V    󰄡󰄟󰄠󰄞󰁬󰁭󰁮󰄢󰄣󰅞󰁫
  C    󰂘󰂙󰀊󰂚󰀋󰂛󰀉󰁻
  X    󰁲󰄩󰄪󰄫󰅀󰄭󰄯󰄰󰁴󰄮󰁳󰄬󰁵󰄱
)
EtymologyList:=EtymologyList1 "`r`n" EtymologyList2 "`r`n" EtymologyList3 "`r`n" EtymologyList4 "`r`n" EtymologyList5
EtymologyList:=RegExReplace(EtymologyList,"[\r\n]{2,}","`r`n"),TMPList:=""
Loop,Parse,EtymologyList,`n,`r
{
	if A_LoopField~="^[\s\t]*[a-zA-Z][\s\t]+[^\x00-\xff]+"{
		TMPList.=RegExReplace(RegExReplace(A_LoopField,"^[\s\t]+"),"[\s\t]{2,}","`t") "`r`n"
	}else if A_LoopField~="^[\s\t]+[^\x00-\xff]+"{
		TMPList:=RTrim(TMPList,"`r`n") RegExReplace(A_LoopField,"[\s\t]") "`r`n"
	}
}
FileDelete,%A_AppData%\RimeToolData\Tips\EtymologyTable.txt
FileAppend,% RTrim(TMPList,"`r`n"),%A_AppData%\RimeToolData\Tips\EtymologyTable.txt,UTF-8
}
;;=======================================================================================
;;===================================托盘菜单=============================================
Menu, TRAY, NoStandard
Menu, TRAY, DeleteAll
Menu, Tray, UseErrorLevel
Menu, TRAY,Add, 关于,Onabout
Menu, TRAY,Add, 资源库,OnHelp
Menu, TRAY,Add,
Menu, TRAY,Add, 码元图,OnView
Menu, TRAY,Add, 编码查询,OnSearch
Menu, TRAY,Add, 码元导入,SplitEtymologyTable
Menu, TRAY,Add, 鼠标划选,Toggle_rlk
if IsRlk {
	Menu, TRAY,Check, 鼠标划选
}
Menu, TRAY,Add,
Menu, TRAY,Add, 开机自启,AutoRunTool
Menu, TRAY,Add, 程序设置,OnSetting
Menu, TRAY,Add, 
;自启项有效性检测并自动校正
if objCount(TaskActionExecPaths:=GetTaskActionExecPaths(TaskName)){
	if A_IsCompiled {
		if (TaskActionExecPaths[1,1]=A_ScriptFullPath){
			Menu, TRAY,Check, 开机自启
		}Else{
			if DisableAutorun(TaskName){
				if (EnableAutoRun(TaskName)=TaskName)
					Menu, TRAY,Check, 开机自启
			}
		}
	}else{
		if (TaskActionExecPaths[1,1]=A_AhkPath&&TaskActionExecPaths[1,2]=A_ScriptFullPath){
			Menu, TRAY,Check, 开机自启
		}Else{
			if DisableAutorun(TaskName){
				if (EnableAutoRun(TaskName)=TaskName)
					Menu, TRAY,Check, 开机自启
			}
		}
	}
}
Menu, TRAY,Add, 重启程序,OnReload
Menu, TRAY,Add, 退出程序,OnExits
Menu, TRAY,Color,ffffff
Menu, TRAY, Default,码元图
Gosub MenuTip
Tray_Refresh()
;==========================================================================
If (DB._Handle)
	DB.CloseDB()
global DB := New SQLiteDB
If !DB.OpenDB(A_AppData "\RimeToolData\Tips\Wubi.db"){
	MsgBox, 262160, 数据库DB错误, % "消息:`t" DB.ErrorMsg "`n代码:`t" DB.ErrorCode
}

;================================反查数据非空检查==========================================
If FileExist(A_AppData "\RimeToolData\Tips\Wubi_dz.txt") {
	DB.GetTable("PRAGMA table_info('danzi');",Result)
	if (Result.RowCount<5)
		Create_Biao(DB,"danzi")
	DB.GetTable("SELECT count(*) FROM danzi;",Result)
	if (Result.RowCount[1,1]<25) {
		__Chars:=""
		if Chars:=GetFileContent(A_AppData "\RimeToolData\Tips\Wubi_dz.txt"){
			if Chars~="[^\x00-\xff]+\t[^\x00-\xff]+\t[a-zA-Z]+" {
				Loop,parse,Chars,`n,`r
				{
					If A_LoopField {
						CharsArr:=StrSplit(A_LoopField,"`t")
						if CharsArr[1]
							__Chars .="('" a_index "','" CharsArr[1] "','" (CharsArr[2]) "','" (CharsArr[3]?CharsArr[3]:"") "','" (CharsArr[4]?CharsArr[4]:"") "')" ","
					}
				}
				if __Chars:=RTrim(__Chars,"`,")
					DB.Exec("INSERT INTO 'main'.'danzi' VALUES" __Chars ";")
			}
		}
	}
	__Chars:=Chars:="",CharsArr:=[]
}

if (A_PtrSize>4)
	SetRegView, 64
RegRead, 360path, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\360safe.exe, path
Process,Exist,360Tray.exe
if (FileExist(360path)||ErrorLevel){
	MsgBox,262192,Warning,您的电脑上运行了「360安全卫士」可能会`n影响本工具的使用，请退出360或添加信任！,10
}
EmptyMem()

;;监控消息回调ShellIMEMessage监控窗口变化
Gui +LastFound
DllCall( "RegisterShellHookWindow", UInt,WinExist() )
OnMessage( DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ), "ShellIMEMessage")
ShellIMEMessage( wParam,lParam ) {
	/*    wParam参数：
		;1 顶级窗体被创建 	;2 顶级窗体即将被关闭 	;54 退出全屏	;32772 窗口切换
		;3 SHELL 的主窗体将被激活 	;4 顶级窗体被激活 	;&H8000& 掩码 	;53 全屏
		;5 顶级窗体被最大化或最小化 	;6 Windows 任务栏被刷新，也可以理解成标题变更
		;7 任务列表的内容被选中 	;8 中英文切换或输入法切换 	;13 wParam=被替换的顶级窗口的hWnd 
		;9 显示系统菜单 	;10 顶级窗体被强制关闭 	;14 wParam=替换顶级窗口的窗口hWnd
		;12 没有被程序处理的APPCOMMAND。见WM_APPCOMMAND
	*/
	Global ttpos_3,FontName,ToolTipStyle
	if !FileExist(A_AppData "\RimeToolData\Tips\Wubi_dz.txt")
		FileCopy,%A_AppData%\RimeToolData\TMP\Wubi_dz.txt,%A_AppData%\RimeToolData\Tips\Wubi_dz.txt
	if !FileExist(A_AppData "\RimeToolData\Tips\Wubi.png")
		FileCopy,%A_AppData%\RimeToolData\TMP\Wubi.png,%A_AppData%\RimeToolData\Tips\Wubi.png
	;监控桌面logo的位置
	WinGetClass, class, A
	if (class<>"Windows.UI.Core.CoreWindow"){
		;;FileAppend,% Format("0x{:x}",lParam) "`n" class "`n",%A_Desktop%\info.txt
		Gosub DeskTopTip
		Gosub MenuTip
	}
	;消除重复运行程序时弹出”Could not close the previous instance of this script. Keep waiting“窗口
	if WinExist(A_ScriptName){
		ControlGetText, WinStaticText , Static1,A
		if WinStaticText {
			if InStr(WinStaticText,"keep Waiting"){
				WinSet,AlwaysOnTop,On,A
				WinActivate ,A
				ControlFocus,Button1
				ControlSend , Button1, {Enter}, A
				if ErrorLevel {
					Send,{Enter}
				}
				Gosub OnReload
			}
		}
	}

	;;桌面logo鼠标穿透
	if objcount(ttpos_3)
		WinSet, ExStyle, ^0x20, % "ahk_id " ttpos_3.HWND   ;;鼠标穿透
	;;98WB-3字体有效性检测
	if (!InStr(GetFontList(),"98WB-3")&&FontName="98WB-3"){
		if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
		{
			AddFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
		}else{
			FontName:=A_AppData . "\RimeToolData\TMP\98WB-3.otf"
		}
	}
	EmptyMem()
}

TrayIconInfo:=TrayIcon_GetInfo(A_IsCompiled?A_ScriptName:RegExReplace(A_AhkPath,".+\\"))
;;检查开机自启后丢失托盘图标并处理
if (!A_IconHidden) {
	if (A_IsCompiled&&!objcount(TrayIconInfo)){
		Gosub OnReload
	}else if (!A_IsCompiled&&!objcount(TrayIconInfo)){
		Gosub OnReload
	}else if (!A_IsCompiled&&objcount(TrayIconInfo)){
		IsNoHide:=0
		for key,value In TrayIconInfo
		{
			if (value.pid=DllCall("GetCurrentProcessId"))
				IsNoHide++
		}
		if !IsNoHide
			Gosub OnReload
	}
}
;;程序图标隐藏托盘提醒
if objcount(TrayIconInfo:=TrayIcon_GetInfo(A_IsCompiled?A_ScriptName:RegExReplace(A_AhkPath,".+\\"))){
	for key,value In TrayIconInfo
	{
		if (InStr(TrayIconInfo[key,"Tray"],"NotifyIconOverflowWindow")&&TrayIconInfo[key,"pid"]=DllCall("GetCurrentProcessId")){
			if !A_IconHidden {
				Traytip,Warning Notify,请把程序图标从托盘区移至`n任务栏以方便更好的操作！,,1
				WinShow,ahk_class NotifyIconOverflowWindow
			}Else{
				MsgBox, 262144, Warning Notify,请把程序图标从托盘区移至`n任务栏以方便更好的操作！,10
				WinShow,ahk_class NotifyIconOverflowWindow
			}
		}
	}
}

~Esc::
	if (objcount(ttpos_1)||objcount(ttpos_2)) {
		if WinExist("ahk_id " ttpos_1.HWND)||WinExist("ahk_id " ttpos_2.HWND)||WinExist("ahk_id " ttpos_4.HWND)
			KeyWait, Esc,D
			btt("",,,2),btt("",,,1),btt("",,,4),btt("",,,5),btt("",,,6),ttpos_1:={},ttpos_2:={},ttpos_4:={}
			KeyWait, Esc
	}
Return

$^MButton::
	MouseGetPos, , , Mid,MControl
	SetAlwaysOnTop(Mid)
Return
;==========================================================================
;==========================================================================
;==========================================================================
;==========================================================================
ControlRButton:
	if (A_TickCount-TickCount_R>150||!TickCount_R){
		ttpos_1:=[],ttpos_2:=[],ttpos_3:=[],WubiInfo:="",TickCount_R:=A_TickCount
		if (!WubiInfo&&!Select_Color_Mode){
			ToolTip(1,""),btt( "",,,1),btt( "",,,2),btt("",,,4),btt("",,,5),btt("",,,6),ttpos_1:={},ttpos_2:={},ttpos_4:={},EmptyMem()
		}
		SetKeyDelay, -1
		KeyWait, RButton ,D
		MouseGetPos,RButtonPosX,RButtonPosY,RID, WhichControl
		WinGetClass,ProcessName,ahk_id %RID%
		Global Win_Explorer_Class1
		if !Clipboard {
			Clipboard:="`r`n"
		}
		if (ProcessName<>"Explorer.EXE")
		{
			WinGetClass,Win_Explorer_Class1,A
			if (Win_Explorer_Class1&&A_PtrSize>4) {
				SysGet,SM_CYCAPTION,4
				SM_CYCAPTION:=SM_CYCAPTION?SM_CYCAPTION:35
				if (RButtonPosY>SM_CYCAPTION&&RButtonPosY<A_ScreenHeight-100){
					Gosub Label_MenuContext_Explorer
				}
			}
		}
	}
Return

ControlLButton:
	if (A_TickCount-TickCount_L>200||!TickCount_L){
		ttpos_1:=[],ttpos_2:=[],ttpos_3:=[],WubiInfo:="",TickCount_L:=A_TickCount
		if (!WubiInfo&&!Select_Color_Mode){
			ToolTip(1,""),btt( "",,,1),btt( "",,,2),btt("",,,4),btt("",,,5),btt("",,,6),ttpos_1:={},ttpos_2:={},ttpos_4:={},EmptyMem()
		}
		SetKeyDelay, -1
		KeyWait, LButton ,D
		MouseGetPos,x1,y1,Mid,MControl
		WinGetTitle,WinTitle1
		KeyWait, LButton
		MouseGetPos,x2,y2,Mid,MControl
		WinGetTitle,WinTitle2
		SysGet, _height, 14       ;获取光标高度
		if (abs(x1-x2) > 10&&IsRlk&&WinTitle1=WinTitle2&&abs(y1-y2) <=_height*8&&Not MControl~="i)syslistview|ToolbarWindow|MSTaskListWClass|systreeview|DirectUIHWND") {
			if ((Click_TickCount:=A_Now-ClickTime)>3&&!IsRuning){
				FileAppend,% Click_TickCount "`n",%A_Temp%\ClickInfo.txt
				ClickTime:=A_Now,IsRuning:=1
				Gosub searchWubi
				IsRuning:=0
			}Else
				btt("请不要暴击！与上一次`n划选时间至少间隔4秒！",,,5,{FontSize:14})
		}
	}
Return

SetAlwaysOnTop(HWND){
	Global SettingGui,GuiAlwaysOnTop,handle_top,LightTheme,handle_8,handle_7
	if WinExist("ahk_id " HWND) {
		WinGet, ExStyle, ExStyle, ahk_id %HWND%
		WinGet, ProcessPath, ProcessPath , ahk_id %HWND%
		FileDescription:=FileGetInfo(ProcessPath, "FileDescription")
		if (ExStyle & 0x8){
			DetectHiddenWindows, On
			WinGetTitle,WinTitle,ahk_id %HWND%
			if (WinTitle&&InStr(WinTitle,"已置顶")){
				WinTitle:=StrReplace(WinTitle,"【已置顶】")
				WinSetTitle, ahk_id %HWND%, , %WinTitle%
			}
			DetectHiddenWindows, Off
			WinSet, AlwaysOnTop, Off, ahk_id %HWND%
			if FileDescription
				TrayTip,%FileDescription%,已取消置顶当前窗口！,,1
		}else{
			DetectHiddenWindows, On
			WinGetTitle,WinTitle,ahk_id %HWND%
			if (WinTitle&&!InStr(WinTitle,"已置顶")){
				WinTitle:=WinTitle . "【已置顶】"
				WinSetTitle, ahk_id %HWND%, , %WinTitle%
			}
			DetectHiddenWindows, Off
			WinSet, AlwaysOnTop, On, ahk_id %HWND%
			if FileDescription
				TrayTip,%FileDescription%,窗口已置顶！,,1
		}
		if (WinExist("ahk_id " SettingGui)=HWND&&WinExist("ahk_id " SettingGui)){
			GuiAlwaysOnTop:=!GuiAlwaysOnTop
			GuiControl, Setting:, closeGui_4,% "HBITMAP:*" (GuiAlwaysOnTop?handle_top:LightTheme?handle_8:handle_7)
		}
	}
}

Label_MenuContext_Explorer: 
	Global MenuContext_RightClickAgain := "-> MenuContext: Right Click Again instead of regular click <-" 
	Global MenuContext_NoClicked_AddedItem := "-> MenuContext: Added items have not been clicked <-"
	Global MenuContext_Separator := "-> MenuContext: Separator <-" 
	Global MenuContext_Item := "-> MenuContext: Standard Item <-"
	Global MenuContext_Submenu := "-> MenuContext: Popup Submenu <-"
	;下面是添加右键菜单项
	NewItemsName:=["显示98五笔拆分","置顶/取消置顶窗口"]
	InsertItemsAtPosition := 1  ; 从右菜单第几项开始插入。
	ArrayToAddItems := { }
	ArrayToAddItems.Push( Fct_MenuContext_Item(NewItemsName[1]) )
	ArrayToAddItems.Push( Fct_MenuContext_Separator() )
	ArrayToAddItems.Push( Fct_MenuContext_Item(NewItemsName[2]) ) ; 添加第2个
	;;ArrayToAddItems.Push( Fct_MenuContext_Separator() )     ; 添加下划线
	TargetProgram_Classes := [ Win_Explorer_Class1 ]
	GetCursorPos(IsRButton_X,IsRButton_Y),GetClipText:=WinClipFunc("",0,1)
	; 判断你点击了哪个菜单项
	ClickedItem := Fct_Get_ClickedItem_MenuContext_AddedItems( TargetProgram_Classes, InsertItemsAtPosition, ArrayToAddItems*)
	If ( ClickedItem = NewItemsName[1] ) {
		Gosub searchWubi
		DllCall("SetCursorPos", "int", IsRButton_X, "int", IsRButton_Y)
		WinActivate,ahk_id %RID%
	}Else if (ClickedItem = NewItemsName[2]) {
		SetAlwaysOnTop(RID:=WinActive("A"))
		WinActivate,ahk_id %RID%
	}Else If ( ClickedItem = False ){
		Return
	}
	IsRButton_X:=0,IsRButton_Y:=0
Return

MenuTip:
	Menu, Tray,Tip, % "♨王码五笔反查助手v" . versions . (A_PtrSize>4?"｜64-bit":"｜32-bit") . "`n - 用鼠标划选文本`n - 划选开关快捷键：" . Format_hotkey(Switch_hotkey) . "`n - 「Ctrl+鼠标中键」置顶(取消置顶)当前窗口" . (A_PtrSize>4?"`n - 划选字符后右键菜单选择「显示98五笔拆分」":"") . ("`n - 当划选偶尔失效时，「" . Format_hotkey(Tip_hotkey) "」键触发反查。")
	WinGetPos,Shell_WndX,Shell_WndY,Shell_WndW,Shell_Wnd ,ahk_class Shell_TrayWnd
	grayLevel:=GetgrayLevel(FormatColor(GetColor(Shell_WndX+5,Shell_WndY)))
	Menu, Tray,Icon,% "HBITMAP:*" (grayLevel < 192?handle_TrayIcon2:handle_TrayIcon1)
Return

AutoRunTool:
	if IsAutoRun:=EnableAutoRun(TaskName) {
		if (IsAutoRun=1){
			Menu, Tray, Uncheck, 开机自启
			traytip,王码五笔反查助手,已取消开机自启计划任务！,,1
		}Else{
			Menu, Tray, Check, 开机自启
			traytip,王码五笔反查助手,已建立开机自启计划任务！,,1
		}
	}else{
		traytip,Error,建立开机自启计划任务失败！,,3
	}
Return

Select_Color_func:
	if Select_Color_Mode {
		Select_Color_Mode:=!Select_Color_Mode
		SetTimer, WatchCursor, Off
		Switch button_label
		{
			Case "ColorInfo1":
				BgColorStart:=TipIni.Settings["BgColorStart"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
			Case "ColorInfo2":
				BgColorEnd:=TipIni.Settings["BgColorEnd"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
			Case "ColorInfo3":
				BorderColorStart:=TipIni.Settings["BorderColorStart"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
			Case "ColorInfo4":
				TextColorStart:=TipIni.Settings["TextColorStart"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
			Case "ColorInfo5":
				BorderColorEnd:=TipIni.Settings["BorderColorEnd"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
			Case "ColorInfo6":
				TextColorEnd:=TipIni.Settings["TextColorEnd"]:=CursorColor,TipIni.save(),btt(""),ToolTip(1,"")
		}
		Hotkey,$LCtrl,Select_Color_func,Off
	}
Return


;;码元表导入处理
SplitEtymologyTable(FilePath:="",flag:=0){
	Global EtymologyList,EtymologyList1,EtymologyList2,EtymologyList3,EtymologyList4,EtymologyList5
	if (A_ThisMenuItemPos||flag&&!FilePath) {
		Gui,+OwnDialogs
		FileSelectFile, FilePath, 3, %A_Desktop%\, 请选择五笔码元(25组)表文件，格式：字母[A-Y]+Tab+键位所有码元, Text Documents (*.txt)
	}
	if (FilePath <> ""){
		EtymologyTable:=GetFileContent(FilePath)
		EtymologyTable:=RegExReplace(EtymologyTable,"[\t]{2,}","`t")
		Lines:=CountLines(EtymologyTable),Count:=0
		if (Lines>24&&EtymologyTable~="[a-zA-Z]\t[^\x00-\xff]+"){
			Loop,Parse,EtymologyTable,`n,`r
			{
				tarr:=StrSplit(A_LoopField,"`t")
				if tarr[1] ~="i)^[gfdsa]$" {
					if (objcount(obj:=GetCharsPhrase(tarr[2]))>22){
						PhraseList:=""
						Loop,% objcount(obj)
						{
							if (A_Index=22||A_Index=44)
								PhraseList.="`r`n      " . obj[A_Index]
							Else
								PhraseList.= obj[A_Index]
						}
						if PhraseList
							Count++,List1.=tarr[1] . "    " . PhraseList . "`r`n"
						Else
							Count++,List1.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}Else{
						Count++,List1.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}
				}else if tarr[1] ~="i)^[hjklm]$" {
					if (objcount(obj:=GetCharsPhrase(tarr[2]))>22){
						PhraseList:=""
						Loop,% objcount(obj)
						{
							if (A_Index=22&&objcount(obj)>25)
								PhraseList.="`r`n      " . obj[A_Index]
							Else
								PhraseList.= obj[A_Index]
						}
						if PhraseList
							Count++,List2.=tarr[1] . "    " . PhraseList . "`r`n"
						Else
							Count++,List2.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}Else{
						Count++,List2.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}
				}else if tarr[1] ~="i)^[trewq]$" {
					if (objcount(obj:=GetCharsPhrase(tarr[2]))>22){
						PhraseList:=""
						Loop,% objcount(obj)
						{
							if (A_Index=22&&objcount(obj)>25)
								PhraseList.="`r`n      " . obj[A_Index]
							Else
								PhraseList.= obj[A_Index]
						}
						if PhraseList
							Count++,List3.=tarr[1] . "    " . PhraseList . "`r`n"
						Else
							Count++,List3.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}Else{
						Count++,List3.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}
				}else if tarr[1] ~="i)^[yuiop]$" {
					if (objcount(obj:=GetCharsPhrase(tarr[2]))>22){
						PhraseList:=""
						Loop,% objcount(obj)
						{
							if (A_Index=22&&objcount(obj)>25)
								PhraseList.="`r`n      " . obj[A_Index]
							Else
								PhraseList.= obj[A_Index]
						}
						if PhraseList
							Count++,List4.=tarr[1] . "    " . PhraseList . "`r`n"
						Else
							Count++,List4.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}Else{
						Count++,List4.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}
				}else if tarr[1] ~="i)^[nbvcx]$" {
					if (objcount(obj:=GetCharsPhrase(tarr[2]))>22){
						PhraseList:=""
						Loop,% objcount(obj)
						{
							if (A_Index=22&&objcount(obj)>25)
								PhraseList.="`r`n      " . obj[A_Index]
							Else
								PhraseList.= obj[A_Index]
						}
						if PhraseList
							Count++,List5.=tarr[1] . "    " . PhraseList . "`r`n"
						Else
							Count++,List5.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}Else{
						Count++,List5.=RegExReplace(A_LoopField,"\t","    ") . "`r`n"
					}
				}
			}
			if (Count>24){
				EtymologyList1:="※※※※※※※横区(G-A)※※※※※※※`r`n" . RTrim(StringUpper(List1),"`r`n")
				,EtymologyList2:="※※※※※※※竖区(H-M)※※※※※※※`r`n" . RTrim(StringUpper(List2),"`r`n")
				,EtymologyList3:="※※※※※※※撇区(T-Q)※※※※※※※`r`n" . RTrim(StringUpper(List3),"`r`n")
				,EtymologyList4:="※※※※※※※捺区(Y-P)※※※※※※※`r`n" . RTrim(StringUpper(List4),"`r`n")
				,EtymologyList5:="※※※※※※※折区(N-X)※※※※※※※`r`n" . RTrim(StringUpper(List5),"`r`n")
				,EtymologyList:=List1 . List2 . List3 . List4 . List5
				FileDelete,%A_AppData%\RimeToolData\Tips\EtymologyTable.txt
				FileAppend,% RegExReplace(RegExReplace(EtymologyList,"[\s]{4}","`t"),"[\t]{2,}"),%A_AppData%\RimeToolData\Tips\EtymologyTable.txt,UTF-8
				if A_ThisMenuItemPos
					TrayTip,王码五笔反查助手,%Count%组码元导入成功！！,,1
				Return 1
			}
		}
		TrayTip,王码五笔反查助手,文件格式不正确，导入失败！,,3
		Return 0
	}
	Return 0
}

Onabout(){
	;默认浏览器打开
	Run, https://gitee.com/leeonchiu/wb98-learning-assistant/releases,, UseErrorLevel
	if (ErrorLevel = "ERROR") {
		;IE浏览器打开
		Run, iexplore.exe "https://gitee.com/leeonchiu/wb98-learning-assistant/releases",, UseErrorLevel
		if (ErrorLevel = "ERROR"){
			;MSEdge浏览器打开
			Run, msedge.exe "https://gitee.com/leeonchiu/wb98-learning-assistant/releases",, UseErrorLevel
		}
	}
}

OnHelp:
	Run, http://98wb.ys168.com/,, UseErrorLevel
	if (ErrorLevel = "ERROR") {
		Run, iexplore.exe "http://98wb.ys168.com/",, UseErrorLevel
		if (ErrorLevel = "ERROR"){
			Run, msedge.exe "http://98wb.ys168.com/",, UseErrorLevel
		}
	}
Return

DeskTopTip:
	Style3 := {BorderColor:0x00ffffff
		, TextColorLinearGradientStart:IsRlk?0xff00b4db:0xff112233
		, TextColorLinearGradientEnd:IsRlk?0xffe81010:0xffb0b0b0
		, TextColorLinearGradientAngle:0
		, TextColorLinearGradientMode:1
		, BackgroundColor:0x00ffffff
		, FontSize:20
		, FontRender:4
		, FontStyle:"Bold"}
	SysGet, _height, 14       ;获取光标高度
	if A_OSVersion Not in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
	{
		if IsWarning {
			ttpos_3:=btt("鼠标划选开／关：" Format_hotkey(Switch_hotkey),A_ScreenWidth-380,(A_ScreenHeight-(Shell_Wnd+FontSize)*1.35),3,Style3)
			LogoPos:=GetLogoPos(ttpos_3)
			WinMove, % "ahk_id " ttpos_3.HWND, , % LogoPos.x,% LogoPos.y
			WinSet, ExStyle, ^0x20, % "ahk_id " ttpos_3.HWND
		}Else{
			btt("",,,3)
		}
	}
Return
;根据任务栏位置确定桌面logo的位置
GetLogoPos(obj){
	Global Shell_WndX,Shell_WndY,Shell_WndW,Shell_Wnd,_height
	WinGetPos,Shell_WndX,Shell_WndY,Shell_WndW,Shell_Wnd ,ahk_class Shell_TrayWnd
	if (Shell_Wnd<A_ScreenHeight) {
		if (Shell_WndY>0){
			Return {x:A_ScreenWidth-obj.w-Shell_Wnd-_height/2,y:A_ScreenHeight-Shell_Wnd-obj.h,Pos:"Bottom",HWND:obj.HWND}
		}Else{
			Return {x:A_ScreenWidth-obj.w-Shell_Wnd-_height/2,y:Shell_Wnd+_height,Pos:"Top",HWND:obj.HWND}
		}
	}else if (Shell_Wnd=A_ScreenHeight) {
		if (Shell_WndX>0){
			Return {x:_height,y:A_ScreenHeight-Shell_Wndw,Pos:"Right",HWND:obj.HWND}
		}Else{
			Return {x:A_ScreenWidth-obj.w-_height,y:A_ScreenHeight-obj.h-_height,Pos:"Left",HWND:obj.HWND}
		}
	}
}

OnSearch:
	Gui,Search:Destroy
	Gui,Search:Default
	Gui,Search:-Caption +AlwaysOnTop -Theme -SysMenu +Owner +HWNDSearchChars
	Gui,Search:Color, % LightTheme? "ffffff":"000000",% LightTheme? "ffffff":"000000"
	Gui,Search:Margin,10,10
	Gui,Search:Font,% LightTheme?"s13 bold c000000":"s13 bold cffffff",% GetDefaultFontName()
	Gui,Search:Add,GroupBox,% " w" A_ScreenWidth/5+20 "  h60 cMaroon vGroupBox1",五笔单字查询
	GuiControlGet,GBPOS,Search:Pos,GroupBox1
	Gui,Search:Font,% LightTheme?"s16 norm c000000":"s16 norm cffffff"
	Gui,Search:Add,Edit,% "x" GBPOSX+15 " y" GBPOSY+35 " w" A_ScreenWidth/5 " gSearchBianma vSearchBianma HWNDSearchEdit ",
	EM_SetCueBanner(SearchEdit, "输入单字以查询！")
	GuiControlGet,SBPOS,Search:Pos,SearchBianma
	Gui,Search:Add,Picture,% "x+8 yp+4 w" SBPOSH-8 " h-1 BackgroundTrans gcloseSearchGui vcloseSearchGui",% "HBITMAP:*" (LightTheme?handle_2:handle_1)
	GuiControl,Search:Move,GroupBox1,% "w" A_ScreenWidth/5+35+SBPOSH " h" SBPOSH+52
	Gui,Search:Show,% "x" A_ScreenWidth*0.8/2 " y" A_ScreenHeight/8 " AutoSize",单字编码查询
Return

closeSearchGui:
	Try {
		ttpos_1:={},ttpos_2:={},ttpos_4:={}
		btt("",,,2),btt("",,,1),btt("",,,4),btt("",,,5),btt("",,,6),EmptyMem()
	}
	Gui,Search:Destroy
Return

SearchBianma:
	Gui,Search:Submit,NoHide
	if SearchBianma~="[^\x00-\xff]"{
		Gosub SetGdiStyle
		ClipText:=SearchBianma
		Gosub SearchCaretText
	}else{
		Try {
			ttpos_1:={},ttpos_2:={},ttpos_4:={}
			btt("",,,2),btt("",,,1),btt("",,,4),btt("",,,5),btt("",,,6),EmptyMem()
		}
	}
Return

SearchCaretText:
	WinGetPos , xpos, ypos, Width, Height, ahk_id %SearchChars%
	ClipText:=RegExReplace(ClipText,"[\x00-\xff]|\s|\t")
	if ClipText~="[^\x00-\xff]"&&StrLen(ClipText)<25 {
		WubiInfo:="",RowIndex:=["㊀","㊁","㊂","㊃","㊄","㊅","㊆","㊇","㊈"]  ;CaretPos:=GetCaretPos()
		if INDEX:=objcount(obj:=GetCharsPhrase(ClipText)){
			ttpos_danzi:=btt(RegExReplace(example_danzi,"[\x00-\xff]"),,,2,Style2,{JustCalculateSize:1})
			ttpos_Round:= Floor((ttpos_danzi.w)/StrLen(RegExReplace(example_danzi,"[\x00-\xff]")))*2
			Loop,% INDEX
			{
				SQL :="SELECT sino_chars,bianma_chars,zigen,zhuyin FROM danzi WHERE sino_chars = '" obj[A_Index] "' ORDER BY cid DESC;"
				if DB.GetTable(SQL,Result){
					Loop,% Result.RowCount
					{
						if Result.Rows[A_Index,1] {
							thisPhraseInfo:=Result.Rows[A_Index,1] . (Result.Rows[A_Index,2]||Result.Rows[A_Index,3]||Result.Rows[A_Index,4]?":":"")
								. (StrLen(Result.Rows[A_Index,2])=3?Result.Rows[A_Index,2] . "  ":StrLen(Result.Rows[A_Index,2])=2?Result.Rows[A_Index,2] . "    ":Result.Rows[A_Index,2])
								. (Result.Rows[A_Index,2]?"〔 ":"") . Result.Rows[A_Index,3] . (Result.Rows[A_Index,3]?" 〕":"") . Result.Rows[A_Index,4]
								. (Result.Rows[A_Index,2]||Result.Rows[A_Index,3]||Result.Rows[A_Index,4]?(Result.RowCount>1?"  " . RowIndex[A_Index] . "`r`n":"`r`n"):"")
							if !InStr(WubiInfo,RTrim(thisPhraseInfo, "`r`n"))
								WubiInfo.=thisPhraseInfo
						}
					}
				}
			}
			WubiInfo:=RTrim(WubiInfo,"`r`n"),LineCounts:= CountLines(WubiInfo),rlk_obj:=StrSplit(WubiInfo,"`n")
			if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
			{
				ToolTip(1,"", "Q1 B" SubStr(Format("{:X}", BgColorStart),3) " T" SubStr(Format("{:X}", TextColorStart),3) " S" (FontSize>20?FontSize/(A_ScreenDPI/96):FontSize) " F" FontName)
				ToolTip(1, WubiInfo, "x" xpos " y" ypos+height+5)
			}else{
				if ToolTipStyle {
					ttpos:=btt(WubiInfo,xpos,ypos,7,Style1,{JustCalculateSize:1}),ypos:=(ttpos.y+ttpos.h*2>A_ScreenHeight?ypos-10-ttpos.h:ypos+height+10)
					ttpos_1:=btt(WubiInfo ,xpos,ypos,1,Style1,{Transparent:Transparent}),ttpos_H:=ttpos_2.h?ttpos_2.h:btt(headerTip,,,7,Style2,{JustCalculateSize:1}).h
					LineHeight:= Floor((ttpos_1.h-Border-Margin*2)/LineCounts)
				}Else{
					ToolTip(1,"", "Q1 B" SubStr(Format("{:X}", BgColorStart),3) " T" SubStr(Format("{:X}", TextColorStart),3) " S" (FontSize>20?FontSize/(A_ScreenDPI/96):FontSize) " F" FontName)
					ToolTip(1, WubiInfo, "x" xpos " y" ypos+height+5)
				}
			}
		}
	}
Return

EM_SetCueBanner(hWnd, Cue)
{
	static EM_SETCUEBANNER := 0x1501
	return DllCall("User32.dll\SendMessage", "Ptr", hWnd, "UInt", EM_SETCUEBANNER, "Ptr", True, "WStr", Cue)
}

;设置窗口
OnSetting:
	LightTheme:=A_HOUR>5&&A_HOUR<18?1:0
	if !WinExist("ahk_id " SettingGui){
		Gui,Setting:Destroy
		Gui,Setting:Default
		Gui,Setting:-Caption +LastFound HwndSettingGui
		Gui,Setting:Color,% LightTheme?"ffffff":"000000",% LightTheme?"ffffff":"000000"
		Gui,Setting:margin,25,25
		Gui,Setting:Add,Text,% "x0 y+38 w200 0x10 vtextInfo0"
		Gui,Setting:Font,% LightTheme?"c000000 s10":"cffffff s10"
		Gui,Setting:Add,Text,xm y+15 vtextInfo1,背景渐变色:
		Gui,Setting:Add,Button,x+5 yp-5 w70 gchangeColor vColorInfo1,
		Gui,Setting:Add,Button,x+10 yp w70 gchangeColor vColorInfo2,
		GuiControlget,spos_1,Setting:pos,textInfo1
		GuiControlget,spos_2,Setting:pos,ColorInfo1
		Gui,Setting:Add,Text,xm y+20 w%spos_1W% vtextInfo2,边框渐变色:
		Gui,Setting:Add,Button,x+5 yp-5 w70 gchangeColor vColorInfo3,
		Gui,Setting:Add,Button,x+10 yp w70 gchangeColor vColorInfo5,
		Gui,Setting:Add,Text,xm y+20 w%spos_1W% vtextInfo3,字体渐变色:
		Gui,Setting:Add,Button,x+5 yp-5 w70 gchangeColor vColorInfo4,
		Gui,Setting:Add,Button,x+10 yp w70 gchangeColor vColorInfo6,

		Gui,Setting:Add,Text,xm y+20 w%spos_1W% vtextInfo6,边框线厚度:
		Gui,Setting:Add,Edit,x+5 yp-5 gControl_Gui vborderWidth w70 Center Number,% Border
		Gui,Setting:Add, UpDown, Range0-50 , % Border
		Gui,Setting:Add,Button,% "x+10 yp w70 gControl_Gui vbuttonInfo1",字体设置
		GuiControlget,spos_3,Setting:pos,buttonInfo1
		Gui,Setting:Add,Text,xm y+20 vtextInfo4 w%spos_1W%,划选开／关:
		Gui,Setting:Font,% LightTheme?"c000000 s9":"cffffff s9"
		Gui,Setting:Add,Button,% "x+5 yp-5 gchangeHotkey vsetHotkey w" spos_2W*2+10,% Format_hotkey(Switch_hotkey)
		Gui,Setting:Add,Button,x+10 yp gRegisterHotkey vbuttonInfo3,注册
		Gui,Setting:Font,% LightTheme?"c000000 s10":"cffffff s10"
		Gui,Setting:Add,Text,% "xm y+20 vtextInfo5 w" spos_1W,透明度:
		Gui,Setting:Add,Slider,% "x+0 yp-10 w" spos_2W*1.8 " gControl_Gui vSetTransparent Page5 Line5 -Theme Invert TickInterval50 ToolTip Range0-255 0x4 0x20" , % Transparent
		Gui,Setting:Add, Picture,x+5 yp+2 w22 h-1 BackgroundTrans Icon75 vinstallWbFont ginstallWbFont, shell32.dll

		Gui,Setting:Add,Radio,% "x" spos_2X+spos_2W*2+65 " ym+" (A_ScreenDPI/96>1?35:42) " gControl_Gui vTipStyle1 0x20 " ,风格1
		Gui,Setting:Add,Radio,x+85 yp gControl_Gui vTipStyle2 0x20,风格2

		GuiControlget,spos_4,Setting:pos,buttonInfo3
		GuiControl,Setting:Move,setHotkey,% "w" spos_2W*2+5-spos_4W
		GuiControl,Setting:Move,buttonInfo3,% "x" spos_4X-10-spos_4W
		GuiControlget,spos_4,Setting:pos,buttonInfo3

		Gui,Setting:Add,Checkbox,% "x" spos_2X+spos_2W*2+50 " y+20 gControl_Gui vToggle_ShowMaYuanBiao Checked" IsShowMaYuanBiao " 0x20",码元提示框:
		Gui,Setting:Add,Checkbox,% "x+45 yp gControl_Gui vtoggle_Isrlk Checked" IsRlk " 0x20",划选反查:
		Gui,Setting:Add,Checkbox,% "x" spos_2X+spos_2W*2+50 " y+25 gControl_Gui vtoggle_IsHelp Checked" IsHelp " 0x20",教程提示框:
		Gui,Setting:Add,Checkbox,x+45 yp gControl_Gui vtoggle_IsRounded Checked%IsRounded% 0x20,圆角显示:
		Gui,Setting:Add,Checkbox,% "x" spos_2X+spos_2W*2+50 " y+25 gControl_Gui vtoggle_IsWarning Checked" IsWarning " 0x20",桌面提示框:
		Gui,Setting:Add,Checkbox,x+45 yp gControl_Gui vAddRButtonMenu Checked%IsInsertMenu% 0x20,右键菜单:
		Gui,Setting:Add,Text,% "x" spos_2X+spos_2W*2+50 " y+25 ",手动触发键:
		Gui,Setting:Font,% LightTheme?"c000000 s9":"cffffff s9"
		Gui,Setting:Add,Button,x+5 yp-3 W120 gchangeTipHotkey vsetTipHotkey,% Format_hotkey(Tip_hotkey)
		Gui,Setting:Add,Button,x+10 yp gControl_Gui vbuttonInfo4,注册
		Gui,Setting:Font,% LightTheme?"c000000 s10":"cffffff s10"
		Gui,Setting:Add,Button,% "x" spos_2X+spos_2W*2+50 " y+20 gControl_Gui vbuttonInfo2",数据导入

		Gui,Setting:Add,Picture,% "x8 y8 w24 h-1 BackgroundTrans vcloseGui_1 gcloseGui ",% "HBITMAP:*" (LightTheme?handle_2:handle_1)
		Gui,Setting:Add,Picture,% "x+25 yp w24 h-1 BackgroundTrans vcloseGui_2 gcloseGui",% "HBITMAP:*" (LightTheme?handle_4:handle_3)
		;;Gui,Setting:Add,Picture,% "x+27 yp w24 h-1 BackgroundTrans vcloseGui_3 gcloseGui",% "HBITMAP:*" (LightTheme?handle_6:handle_5)
		Gui,Setting:Add,Picture,% "x+27 yp w24 h-1 BackgroundTrans vcloseGui_4 gcloseGui",% "HBITMAP:*" (GuiAlwaysOnTop?handle_top:LightTheme?handle_8:handle_7)
		Gui,Setting:Font,% LightTheme?"ca0a0a0 s9":"ca0a0a0 s9"
		Gui,Setting:Add,Text,% "x" spos_2X+spos_2W*2+50 " y" spos_2Y-40 " vOsCaption",% OSVersionCaption[1] A_Space OSVersionCaption[2]
		Gui,Setting:Show, AutoSize,提示框设置
		GuiControlget,ospos,Setting:pos,OsCaption
		WinGetPos,posx,posy,posw,posh,ahk_id %SettingGui%
		GuiControl,Setting:Move,textInfo0,% "w" spos_3X+spos_3W*2+300
		GuiControl,Setting:Move,OsCaption,% "x" posw/(A_ScreenDPI/96)-osposW-10
	}Else
		WinActivate,ahk_id %SettingGui%
	For,k,v In [BgColorStart,BgColorEnd,BorderColorStart,TextColorStart,BorderColorEnd,TextColorEnd]
	{
		SetButtonColor("ColorInfo" A_Index, v,,1),SetButtonColor("buttonInfo" k, LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
		GuiControl,Setting:,ColorInfo%A_Index%,
	}
	SetButtonColor("setHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
	SetButtonColor("setTipHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
	for Section,element in {borderWidth:Border,setHotkey:Format_hotkey(Switch_hotkey)
		,setTipHotkey:Format_hotkey(Tip_hotkey),SetTransparent:Transparent,Toggle_ShowMaYuanBiao:IsShowMaYuanBiao,toggle_Isrlk:IsRlk
		,toggle_IsHelp:IsHelp,toggle_IsRounded:IsRounded,toggle_IsWarning:IsWarning,AddRButtonMenu:IsInsertMenu}
	{
		GuiControl,Setting:,%Section% ,% element
	}
	if (A_PtrSize=4)
		GuiControl,Setting:Disable,AddRButtonMenu
	if IsRlk {
		GuiControl,Setting:Enable,Toggle_ShowMaYuanBiao
		GuiControl,Setting:Enable,toggle_IsHelp
	}Else{
		GuiControl,Setting:Disable,Toggle_ShowMaYuanBiao
		GuiControl,Setting:Disable,toggle_IsHelp
	}
	if ToolTipStyle
		GuiControl,Setting:,TipStyle1,1
	Else{
		GuiControl,Setting:,TipStyle2,1
		GuiControl,Setting:Disable,toggle_IsRounded
		GuiControl,Setting:Disable,Toggle_ShowMaYuanBiao
		GuiControl,Setting:Disable,toggle_IsHelp
		GuiControl,Setting:Disable,toggle_IsWarning
		GuiControl,Setting:Disable,SetTransparent
	}
	if GuiAlwaysOnTop
		WinSet, AlwaysOnTop , On, ahk_id %SettingGui%
Return

InstallWbFont:
	FileCreateDir,%A_Desktop%\Font
	FileCopy,%A_AppData%\RimeToolData\TMP\*.otf,%A_Desktop%\Font\*.otf,1
	OpenAndSelect(A_Desktop "\Font\")
Return

OnView:
	Run, rundll32.exe "%A_ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll"`, ImageView_Fullscreen %A_AppData%\RimeToolData\Tips\Wubi.png,, UseErrorLevel
Return

OnExits:
	RemoveFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
	ExitApp
Return

closeGui:
	if A_GuiControl {
		Switch A_GuiControl
		{
			Case "closeGui_1":
				Gosub Select_Color_func
				Gui,Setting:Destroy
				btt("",,,5),EmptyMem()
			Case "closeGui_2":
				WinMinimize , ahk_id %SettingGui%
			Case "closeGui_3":
				LightTheme:=TipIni.Settings["LightTheme"]:=!LightTheme,TipIni.save()
				Gui,Setting:Color,% LightTheme?"ffffff":"000000",% LightTheme?"ffffff":"000000"
				Gui, Setting:Font, % LightTheme?"c000000":"cffffff s10"
				Loop,6
					GuiControl, Setting:Font, textInfo%A_Index%
				for k,v In ["toggle_Isrlk","toggle_IsRounded","borderWidth","TipStyle1","TipStyle2","Toggle_ShowMaYuanBiao","toggle_IsHelp","toggle_IsWarning","IsInsertMenu"]
					GuiControl, Setting:Font, %v%

				GuiControl, Setting:, closeGui_1,% "HBITMAP:*" (LightTheme?(handle_2):handle_1)
				GuiControl, Setting:, closeGui_2,% "HBITMAP:*" (LightTheme?(handle_4):handle_3)
				GuiControl, Setting:, closeGui_3,% "HBITMAP:*" (LightTheme?(handle_6):handle_5)
				GuiControl, Setting:, closeGui_4,% "HBITMAP:*" (GuiAlwaysOnTop?handle_top:LightTheme?handle_8:handle_7)
			Case "closeGui_4":
				GuiAlwaysOnTop:=!GuiAlwaysOnTop
				WinSet, AlwaysOnTop , Toggle, ahk_id %SettingGui%
				GuiControl, Setting:, closeGui_4,% "HBITMAP:*" (GuiAlwaysOnTop?handle_top:LightTheme?handle_8:handle_7)
		}
	}
Return

OnReload:
	Reload
Return

MoveActiveWindows( p_w, p_l, p_m, p_hw ){
	Global ttpos_1,ttpos_2,ttpos_4,SearchChars
	ttpos_1:={},ttpos_2:={},ttpos_4:={}
	btt("",,,2),btt("",,,1),btt("",,,4),btt("",,,5),btt("",,,6)
	PostMessage, 0xA1, 2
}

GetEtymologyInfo(ByRef Chars){
	Global DB
	if !RegExReplace(Chars,"[\x00-\xff]")
		Return
	Chars:=RegExReplace(Chars,"[\x00-\xff]")
	if DB.GetTable("SELECT sino_chars,zigen FROM danzi WHERE sino_chars = '" Chars "' ORDER BY cid DESC;",Result){
		if Result.RowCount {
			Chars:=""
			Loop,% Result.RowCount
				Chars.=Result.Rows[A_Index,1] "｛  " GetCharsPhrase(Result.Rows[A_Index,2],"    ") "  ｝`r`n"
			Return Chars:=RTrim(Chars,"`r`n")
		}Else
			Chars:=""

	}Else
		Chars:=""
	Return Chars
}

WM_MOUSEMOVE( p_w, p_l, p_m, p_hw){
	Global ttpos_1,ttpos_2,ttpos_3,Style4,ttpos_4,EtymologyList,_height,LineHeight,rlk_obj,LineCounts,IsShowMaYuanBiao
		,BackgroundColor,BgColorStart,BgColorEnd,BorderColorEnd,BorderColorStart,TextColorEnd,Border,Margin,ttpos_Round
		,TextColorStart,IsRlk,IsRounded,IsShowMaYuanBiao,Select_Color_Mode,IsHelp,Transparent,ttpos_danzi,IsHelp
		,headerTip,example_danzi,Style1,Style2,style6,headerTip2,headerTip3,FontSize
	GetCursorPos(xpos, ypos),CurRControl := A_GuiControl
	Tip_Show:={ColorInfo1:Format("0x{:X}",BgColorStart),ColorInfo2:Format("0x{:X}",BgColorEnd),setTipHotkey:"点击控件后背景为红色时，请按下`n组合键自动识别，点击「注册」生效！",setHotkey:"点击控件后背景为红色时，请按下`n组合键自动识别，点击「注册」生效！"
		,ColorInfo3:Format("0x{:X}",BorderColorStart),ColorInfo5:Format("0x{:X}",BorderColorEnd),closeSearchGui:"关闭查询框"
		,ColorInfo4:Format("0x{:X}",TextColorStart),ColorInfo6:Format("0x{:X}",TextColorEnd),AddRButtonMenu:"五笔反查功能集成于右键菜单",buttonInfo4:"当划选偶尔失效时，手动`n触发划选字反查的热键。"
		,borderWidth:"GDI提示框`n边框线宽度",buttonInfo1:"字体、字号、样式设置",buttonInfo2:"导入文件格式如下`n「反查数据」：单字+Tab+拆分+Tab+编码+Tab+读音`n「码元源表」：键位字母[a-y]+Tab+相应键位上所有码元",buttonInfo3:"鼠标划选开关切换热键注册"
		,toggle_IsRounded:"GDI提示框圆角显示",toggle_Isrlk:"鼠标划选开启与关闭",Toggle_ShowMaYuanBiao:"鼠标经过反查提示框`n时显示对应码元表，`nGDI提示框有效！"
		,TipStyle1:"GDI绘制风格，适用Win7及以上系统",TipStyle2:"系统默认提示框风格",toggle_IsHelp:"五笔教程提示框",toggle_IsWarning:"桌面快捷键提示框"
		,closeGui_1:"关闭窗口",closeGui_2:"最小化",closeGui_3:"窗口反色",closeGui_4:"置顶",SetTransparent:"设置GDI提示框透明度",InstallWbFont:"如果拆分字根无法显示，请点击`n后安装弹出的目录下的字体！"}
	if A_OSVersion Not in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
	{
		if objcount(ttpos_1)&&IsShowMaYuanBiao {
			if WinExist("ahk_id " ttpos_1.HWND){
				if (xpos>ttpos_1.x&&xpos<(ttpos_1.x+ttpos_1.w)&&ypos>ttpos_1.y&&ypos<(ttpos_1.y+ttpos_1.h)){
					w4:=ttpos_4.w?ttpos_4.w:800,xpos:=xpos+w4>=A_ScreenWidth?xpos-w4-ttpos_1.w-_height/2:xpos
					if (LineCounts>1){
						LineNum:=Floor((ypos-ttpos_1.y+Border+Margin)/LineHeight)
						;;ttpos_4:=btt(EtymologyList,xpos,ypos,4,Style4)
						if LineNum Between 1 And LineCounts
						{
							if match:=GetEtymologyList(rlk_obj[LineNum]) {
								ttpos_4:=btt(match,xpos+_height/2,ypos,4,Style4,{Transparent:Transparent+10>255?255:Transparent})
							}
						}Else{
							btt("",,,4)
						}
					}else{
						if match:=GetEtymologyList(rlk_obj[1]) {
							ttpos_4:=btt(match,xpos+_height/2,ypos,4,Style4,{Transparent:Transparent+10>255?255:Transparent})
						}
					}
				}Else
					btt("",,,4)
			}Else
				btt("",,,4)
		}
		if objcount(ttpos_2)&&IsHelp&&WinExist("ahk_id " ttpos_2.HWND){
			Height:=Floor((ttpos_2.h-(Border+Margin)*2)/(totalLine:=CountLines(headerTip)))
			headerobj:=StrSplit(headerTip,"`n")
			if (ypos>ttpos_2.y&&ypos<ttpos_2.y+ttpos_2.h&&xpos>ttpos_2.x&&xpos<ttpos_2.x+ttpos_2.w){
				LineNum:=Floor((ypos-ttpos_2.y)/Height)
				if LineNum Between 1 And totalLine
				{
					if InStr(example_danzi,str:=RegExReplace(headerobj[LineNum],"[\x00-\xff]")){
						obj:=StrSplit(str,"、"),exnum:=Floor((xpos-ttpos_2.x+Margin+ttpos_Round/2-Border)/ttpos_Round)-1
						len:=objCount(obj)
						if (exnum>0 And exnum<=len){
							btt(GetEtymologyInfo(obj[exnum]),xpos+_height/2,ypos_height/2,6,style6,{Transparent:Transparent+10>255?255:Transparent+10})
						}Else
							btt("",,,6)
					}else if InStr(headerobj[LineNum],"识别码"){
						btt(headerTip2,xpos+_height/2,ypos_height/2,6,Style2,{Transparent:Transparent})
					}else if (InStr(headerobj[LineNum],"助记")||InStr(headerobj[LineNum],"简码")){
						btt(headerTip3,xpos+_height/2,ypos_height/2,6,Style2,{Transparent:Transparent})
					}Else
						btt("",,,6)
				}Else
					btt("",,,6)
			}else{
				btt("",,,6)
			}
		}
		if (CurRControl <> PrevControl and not InStr(CurRControl, " ") And !Select_Color_Mode)
		{
			btt(Tip_Show[CurRControl],xpos+_height*0.4,ypos+_height*0.75,5)
			PrevControl := CurRControl
		}Else{
			btt("",,,5)
		}
	}
}

GetEtymologyList(Chars){
	Global EtymologyList1,EtymologyList2,EtymologyList3,EtymologyList4,EtymologyList5
	list:="",Chars_:="",Count_1:=0,,Count_2:=0,Count_3:=0,Count_4:=0,Count_5:=0
	RegExMatch(Chars,"[a-zA-Z]+",match)
	if match {
		Loop,Parse,match
		{
			if !InStr(Chars_,A_LoopField){
				Chars_.=A_LoopField
				if A_LoopField In g,f,d,s,a
				{
					if !Count_1
						Count_1:=!Count_1,Result.=EtymologyList1 "`r`n`r`n"
				}
				else if A_LoopField In h,j,k,l,m
				{
					if !Count_2
						Count_2:=!Count_2,Result.=EtymologyList2 "`r`n`r`n"
				}
				else if A_LoopField In t,r,e,w,q
				{
					if !Count_3
						Count_3:=!Count_3,Result.=EtymologyList3 "`r`n`r`n"
				}
				else if A_LoopField In y,u,i,o,p
				{
					if !Count_4
						Count_4:=!Count_4,Result.=EtymologyList4 "`r`n`r`n"
				}
				else if A_LoopField In n,b,v,c,x
				{
					if !Count_5
						Count_5:=!Count_5,Result.=EtymologyList5 "`r`n`r`n"
				}
			}
		}
		if Result
			Result:="         ｛ " Chars " ｝`r`n`r`n" Result
	}
	Return Result~="\n[\s]{4,}[^\x00-\xff]+"?Result:RTrim(Result,"`r`n`r`n")
}

RegisterHotkey:
	Gui,Setting:Default
	SetButtonColor("setHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
	GuiControlGet,setHotkey,, setHotkey,Text
	if (setHotkey:=Format_hotkey2(setHotkey)) {
		Hotkey,$%Switch_hotkey%,Toggle_rlk,Off
		Switch_hotkey:=TipIni.Settings["Switch_hotkey"]:=setHotkey?setHotkey:Switch_hotkey,TipIni.save()
		Hotkey,$%Switch_hotkey%,Toggle_rlk,On
		if ErrorLevel {
			Switch ErrorLevel
			{
				Case 1:
					MsgBox, 262160,Error,指定的标签不存在！
				Case 2:
					MsgBox, 262160,Error,指定的键位在当前键盘布局/语言无法识别或不支持！
				Case 3:
					MsgBox, 262160,Error,包含不支持的前缀键！
				Case 4:
					MsgBox, 262160,Error,热键不合组合规范！
				Case 5:
					MsgBox, 262160,Error,命令试图修改不存在的热键！
				Case 6:
					MsgBox, 262160,Error,命令试图修改现有热键的不存在的变体！
				Case 98:
					MsgBox, 262160,Error,超过每个脚本热键数量的限制！
				Case 99:
					MsgBox, 262160,Error,内存不足！
			}
		}
		if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
		{
			TrayTip,Hotkey Notify,% "热键" Format_hotkey(Switch_hotkey) "注册成功！",,1
		}
		Gosub MenuTip
		Gosub DeskTopTip
	}
Return

changeHotkey:
	Gui,Setting:Default
	SetButtonColor("setHotkey", "0xE81010",,1)
	Gui, Setting:Submit,NoHide
	if ComboKey:=WaitComboKey(){
		if (ComboKey<>Tip_hotkey){
			GuiControl,Setting:,setHotkey,% Format_hotkey(ComboKey)
			RefreshButton("setHotkey")
		}Else
			TrayTip,Hotkey Warning,该组合热键已存在！,,2
	}
	SetButtonColor("setHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
Return

changeTipHotkey:
	Gui,Setting:Default
	SetButtonColor("setTipHotkey", "0xE81010",,1)
	Gui, Setting:Submit,NoHide
	if ComboKey:=WaitComboKey(){
		if (ComboKey<>Switch_hotkey){
			GuiControl,Setting:,setTipHotkey,% Format_hotkey(ComboKey)
			RefreshButton("setTipHotkey")
		}Else
			TrayTip,Hotkey Warning,该组合热键已存在！,,2
	}
	SetButtonColor("setTipHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
Return

RefreshButton(Section){
	Global Switch_hotkey,Tip_hotkey
	for key,value In {buttonInfo1:"字体设置",setHotkey:Format_hotkey(Switch_hotkey),buttonInfo2:"数据导入"
		,buttonInfo3:"注册",buttonInfo4:"注册",setTipHotkey:Format_hotkey(Tip_hotkey)}
	{
		Gui,Setting:Default
		if (key<>Section)
			GuiControl,Setting:,%key%,% value
	}
}

Control_Gui:
	if A_GuiControl{
		Switch A_GuiControl
		{
			case "buttonInfo1":
				Gui,+OwnDialogs
				if objcount(fontObject:=FontSelect({name:FontName,Style:FontStyle,size:FontSize})){
					FontStyle_:=""
					for k,v in ["FontName","FontSize","bold","italic","underline","strikeout"]
					{
						Switch v
						{
							Case "FontName":
								FontName:=TipIni.Settings["FontName"]:=fontObject["name"]?fontObject["name"]:FontName
							Case "FontSize":
								FontSize:=TipIni.Settings["FontSize"]:=fontObject["size"]?fontObject["size"]:FontSize
							Case "bold":
								FontStyle_.=InStr(fontObject["bold"],"bold")?"bold ":"norm"
							Case "italic":
								FontStyle_.=InStr(fontObject["italic"],"italic")?"italic ":InStr(FontStyle,"italic")?"italic ":""
							Case "underline":
								FontStyle_.=InStr(fontObject["underline"],"underline")?"underline ":InStr(FontStyle,"underline")?"underline ":""
							Case "strikeout":
								FontStyle_.=InStr(fontObject["strike"],"strike")?"strikeout ":InStr(FontStyle,"strike")?"strikeout ":""
						}
					}

					FontStyle:=TipIni.Settings["FontStyle"]:=RTrim( FontStyle_,A_Space),TipIni.save()
				}
			case "buttonInfo2":
				Gui,+OwnDialogs
				MsgBoxRenBtn("导入反查源表","导入码元源表","取消")
				MsgBox, 262147, 数据导入,「反查源表」格式：单字+Tab+拆分+Tab+编码+Tab+读音`n「码元源表」格式：字母[a-y]+Tab+相应键位上所有的码元
				IfMsgBox, Yes
				{
					Gui,+OwnDialogs
					FileSelectFile, FilePath, 3, %A_AppData%\RimeToolData\Tips\Wubi_dz.txt, TXT文本导入格式：单字+Tab+拆分+Tab+编码+Tab+读音, Text Documents (*.txt)
					if (FilePath <> ""){
						__Chars:=""
						if Chars:=GetFileContent(FilePath){
							if Chars~="[^\x00-\xff]+\t[^\x00-\xff]+\t[a-zA-Z]+" {
								TrayTip,王码五笔反查助手,文件处理中请稍候。。。,,1
								Loop,parse,Chars,`n,`r
								{
									If A_LoopField {
										CharsArr:=StrSplit(A_LoopField,"`t")
										if CharsArr[1]
											__Chars .="('" a_index "','" CharsArr[1] "','" (CharsArr[2]) "','" (CharsArr[3]?CharsArr[3]:"") "','" (CharsArr[4]?CharsArr[4]:"") "')" ","
									}
								}
								if __Chars:=RTrim(__Chars,"`,"){
									Create_Biao(DB,"danzi")
									if DB.Exec("INSERT INTO 'main'.'danzi' VALUES" __Chars ";")
										TrayTip,王码五笔反查助手,导入成功，以鼠标划选文本进行反查！,,1
								}Else
									TrayTip,王码五笔反查助手,文件处理失败，请检查文本格式！,,3
							}Else
								TrayTip,王码五笔反查助手,文本格式有误，格式：单字+Tab+拆分+Tab+编码+Tab+读音！,,3
						}Else
							TrayTip,王码五笔反查助手,文本为空，请重新选择！,,3
						__Chars:=Chars:="",CharsArr:=[],EmptyMem()
					}
				}
				else IfMsgBox, No
				{
					SplitEtymologyTable("",1)
				}
			case "borderWidth":
				GuiControlGet,borderWidth,,borderWidth,text
				if (borderWidth>50||borderWidth<0){
					borderWidth:=6
					GuiControl,Setting:,borderWidth,%borderWidth%
				}
				Border:=TipIni.Settings["Border"]:=borderWidth<>""?borderWidth:6,TipIni.save()
			case "toggle_Isrlk":
				GuiControlGet,toggle_Isrlk,,toggle_Isrlk,Checkbox
				IsRlk:=TipIni.Settings["IsRlk"]:=toggle_Isrlk,TipIni.save()
				if IsRlk {
					GuiControl,Setting:Enable,Toggle_ShowMaYuanBiao
					GuiControl,Setting:Enable,toggle_IsHelp
					Menu, TRAY,Check, 鼠标划选
				}Else{
					GuiControl,Setting:Disable,Toggle_ShowMaYuanBiao
					GuiControl,Setting:Disable,toggle_IsHelp
					Menu, TRAY,Uncheck, 鼠标划选
				}
				Gosub DeskTopTip
			case "toggle_IsRounded":
				GuiControlGet,toggle_IsRounded,,toggle_IsRounded,Checkbox
				IsRounded:=TipIni.Settings["IsRounded"]:=toggle_IsRounded,TipIni.save()
			case "TipStyle1":
				ToolTipStyle:=TipIni.Settings["ToolTipStyle"]:=1,TipIni.save()
				GuiControl,Setting:Enable,toggle_IsRounded
				GuiControl,Setting:Enable,Toggle_ShowMaYuanBiao
				GuiControl,Setting:Enable,toggle_IsHelp
				GuiControl,Setting:Enable,toggle_IsWarning
				GuiControl,Setting:Enable,SetTransparent
				if (!InStr(GetFontList(),"98WB-3")&&FontName="98WB-3"){
					if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
					{
						AddFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
					}else{
						FontName:=A_AppData . "\RimeToolData\TMP\98WB-3.otf"
					}
				}
			case "TipStyle2":
				ToolTipStyle:=TipIni.Settings["ToolTipStyle"]:=0,TipIni.save()
				GuiControl,Setting:Disable,toggle_IsRounded
				GuiControl,Setting:Disable,Toggle_ShowMaYuanBiao
				GuiControl,Setting:Disable,toggle_IsHelp
				GuiControl,Setting:Disable,toggle_IsWarning
				GuiControl,Setting:Disable,SetTransparent
				if (!InStr(GetFontList(),"98WB-3")&&FontName="98WB-3"){
					AddFontResource(A_AppData "\RimeToolData\TMP\98WB-3.otf")
				}
			Case "Toggle_ShowMaYuanBiao":
				GuiControlGet,Toggle_ShowMaYuanBiao,,Toggle_ShowMaYuanBiao,Checkbox
				IsShowMaYuanBiao:=TipIni.Settings["IsShowMaYuanBiao"]:=Toggle_ShowMaYuanBiao,TipIni.save()
			Case "toggle_IsHelp":
				GuiControlGet,toggle_IsHelp,,toggle_IsHelp,Checkbox
				IsHelp:=TipIni.Settings["IsHelp"]:=toggle_IsHelp,TipIni.save()
			Case "toggle_IsWarning":
				GuiControlGet,toggle_IsWarning,,toggle_IsWarning,Checkbox
				IsWarning:=TipIni.Settings["IsWarning"]:=toggle_IsWarning,TipIni.save()
				Gosub DeskTopTip
			Case "SetTransparent":
				Transparent:=TipIni.Settings["Transparent"]:=SetTransparent,TipIni.save()
			Case "AddRButtonMenu":
				GuiControlGet,AddRButtonMenu,,AddRButtonMenu,Checkbox
				IsInsertMenu:=TipIni.Settings["IsInsertMenu"]:=AddRButtonMenu,TipIni.save()
			Case "buttonInfo4":
				Gui,Setting:Default
				SetButtonColor("setTipHotkey", LightTheme?"0xFFFFFF":"0xE4E4E4",,1)
				GuiControlGet,setTipHotkey,, setTipHotkey,Text
				if (setTipHotkey:=Format_hotkey2(setTipHotkey)) {
					Gui,Setting:Submit,NoHide
					Try
					{
						Hotkey,$%Tip_hotkey%,rlk_label,Off
						Tip_hotkey:=TipIni.Settings["Tip_hotkey"]:= setTipHotkey?setTipHotkey:Tip_hotkey,TipIni.save()
						Hotkey,$%Tip_hotkey%,rlk_label,On
						TrayTip,Hotkey Notify,热键注册成功！,,1
					}Catch{
						Hotkey,$%Tip_hotkey%,rlk_label,On
						Tip_hotkey:=TipIni.Settings["Tip_hotkey"]:= default_value.Settings["Tip_hotkey"],TipIni.save()
						GuiControl,Setting:,setTipHotkey,% Format_hotkey(Tip_hotkey)
						TrayTip,Hotkey Error,热键名不规范，注册出错！,,3
					}
					Gosub MenuTip
				}
		}
	}
Return

changeColor:
	if InStr(A_GuiControl,"ColorInfo") {
		button_label:=A_GuiControl,Select_Color_Mode:=1
		Hotkey,$LCtrl,Select_Color_func,On
		SetTimer, WatchCursor, 100
	}
Return

WatchCursor:
	GetCursorPos(xpos, ypos)
	WinActivate,
	CursorColor:=GetCursorColor(xpos,ypos),ColorInfo:=FormatColor(CursorColor)
	grayLevel:=GetgrayLevel(ColorInfo)
	;;FileAppend,% grayLevel "-" ColorInfo "`n",%A_Desktop%\info.txt
	Style5 := {Border:1
		, Rounded:5
		, FontSize:14
		, BorderColor:grayLevel < 192?"0xffffffff":"0xff000000"
		, TextColor:grayLevel < 192?"0xffffffff":"0xff000000"
		, BackgroundColorLinearGradientStart:RegExReplace(ColorInfo,"0x","0xff")
		, BackgroundColorLinearGradientEnd:RegExReplace(ColorInfo,"0x","0xff")
		, BackgroundColorLinearGradientAngle:0
		, BackgroundColorLinearGradientMode:1}
	if A_OSVersion Not in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
	{
		if (ColorInfo<>""){
			ColorInfo:=RegExReplace(ColorInfo,"i)0xff","0x")
			if ToolTipStyle
				btt("按LCtrl键终止取色`nHex：" ColorInfo "`nRGB：" HexToRGB(ColorInfo,"Parse"),xpos+_height/2,ypos+_height,,Style5)
			else{
				ToolTip(1,"", "Q1 B" SubStr(ColorInfo,5) " T" (grayLevel < 192?"ffffff":"000000") " S12 F" FontName)
				ToolTip(1,"按LCtrl键终止取色`nHex：" ColorInfo "`nRGB：" HexToRGB(ColorInfo,"Parse"), "x" xpos+_height " y" ypos+_height)
			}
		}
	}Else{
		ToolTip(1,"", "Q1 B" SubStr(CursorColor_last,5) " T" (grayLevel < 192?"ffffff":"000000") " S12 F" FontName)
		ToolTip(1, ColorInfo, "x" xpos+_height " y" ypos+_height)
	}
	if CursorColor~="i)^0x[0-9a-fA-F]{5,6}$|0x0$"{
		CursorColor:=FormatColor(CursorColor)
		if (CursorColor_last<>CursorColor){
			CursorColor_last:=CursorColor
			SetButtonColor(button_label,CursorColor)
		}
	}
Return

MatchCaretText:
	ClipText:=RegExReplace(ClipText,"[\x00-\xff]|\s|\t")
	if ClipText~="[^\x00-\xff]"&&StrLen(ClipText)<25 {
		WubiInfo:="",RowIndex:=["㊀","㊁","㊂","㊃","㊄","㊅","㊆","㊇","㊈"]  ;CaretPos:=GetCaretPos()
		if INDEX:=objcount(obj:=GetCharsPhrase(ClipText)){
			ttpos_danzi:=btt(RegExReplace(example_danzi,"[\x00-\xff]"),,,2,Style2,{JustCalculateSize:1})
			ttpos_Round:= Floor((ttpos_danzi.w)/StrLen(RegExReplace(example_danzi,"[\x00-\xff]")))*2
			Loop,% INDEX
			{
				SQL :="SELECT sino_chars,bianma_chars,zigen,zhuyin FROM danzi WHERE sino_chars = '" obj[A_Index] "' ORDER BY cid DESC;"
				if DB.GetTable(SQL,Result){
					Loop,% Result.RowCount
					{
						if Result.Rows[A_Index,1] {
							thisPhraseInfo:=Result.Rows[A_Index,1] . (Result.Rows[A_Index,2]||Result.Rows[A_Index,3]||Result.Rows[A_Index,4]?":":"")
								. (StrLen(Result.Rows[A_Index,2])=3?Result.Rows[A_Index,2] . "  ":StrLen(Result.Rows[A_Index,2])=2?Result.Rows[A_Index,2] . "    ":Result.Rows[A_Index,2])
								. (Result.Rows[A_Index,2]?"〔 ":"") . Result.Rows[A_Index,3] . (Result.Rows[A_Index,3]?" 〕":"") . Result.Rows[A_Index,4]
								. (Result.Rows[A_Index,2]||Result.Rows[A_Index,3]||Result.Rows[A_Index,4]?(Result.RowCount>1?"  " . RowIndex[A_Index] . "`r`n":"`r`n"):"")
							if !InStr(WubiInfo,RTrim(thisPhraseInfo, "`r`n"))
								WubiInfo.=thisPhraseInfo
						}
					}
				}
			}
			WubiInfo:=RTrim(WubiInfo,"`r`n"),GetCursorPos(xpos, ypos),LineCounts:= CountLines(WubiInfo),rlk_obj:=StrSplit(WubiInfo,"`n")
			,xpos:=(InStr(A_PriorHotkey,"RButton")?IsRButton_X:xpos),ypos:=(InStr(A_PriorHotkey,"RButton")?IsRButton_Y:ypos)
			if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_VISTA
			{
				ToolTip(1,"", "Q1 B" SubStr(Format("{:X}", BgColorStart),3) " T" SubStr(Format("{:X}", TextColorStart),3) " S" (FontSize>20?FontSize/(A_ScreenDPI/96):FontSize) " F" FontName)
				ToolTip(1, WubiInfo, "x" xpos+_height " y" ypos+_height)
			}else{
				if ToolTipStyle {
					ttpos:=btt(WubiInfo,xpos,ypos,7,Style1,{JustCalculateSize:1}),ypos:=IsHelp?(ttpos.y+ttpos.h+(bbt2_Height:=btt(headerTip,,,7,Style2,{JustCalculateSize:1}).h)>A_ScreenHeight?ypos-15-ttpos.h-_height:ypos):(ttpos.y+ttpos.h*2>A_ScreenHeight?ypos-_height-ttpos.h:ypos)
					ttpos_1:=btt(WubiInfo,xpos+_height/2,ypos+_height,1,Style1,{Transparent:Transparent}),ttpos_H:=ttpos_2.h?ttpos_2.h:btt(headerTip,,,7,Style2,{JustCalculateSize:1}).h
					LineHeight:= Floor((ttpos_1.h-Border-Margin*2)/LineCounts)
					if (objcount(ttpos_1)&&IsHelp) {
						tty:=(ttpos_1.h+ttpos_1.y+ttpos_H)>=A_ScreenHeight?ttpos_1.y-ttpos_H-_height/2:ttpos_1.h+ttpos_1.y+10
						ttpos_2:=btt(headerTip,xpos+_height/2,tty,2,Style2,{Transparent:Transparent})
					}
				}Else{
					ToolTip(1,"", "Q1 B" SubStr(Format("{:X}", BgColorStart),3) " T" SubStr(Format("{:X}", TextColorStart),3) " S" (FontSize>20?FontSize/(A_ScreenDPI/96):FontSize) " F" FontName)
					ToolTip(1, WubiInfo, "x" xpos+_height " y" ypos+_height)
				}
			}
		}
	}
Return

SetGdiStyle:
	Style1 := {Border:Border
		, Rounded:IsRounded?Round:0
		, Margin:Margin
		, BorderColor:BorderColor
		, BorderColorLinearGradientStart:BorderColorStart
		, BorderColorLinearGradientEnd:BorderColorEnd
		, BorderColorLinearGradientAngle:45
		, BorderColorLinearGradientMode:1
		, TextColor:TextColor
		, TextColorLinearGradientStart:TextColorStart
		, TextColorLinearGradientEnd:TextColorEnd
		, TextColorLinearGradientAngle:70
		, TextColorLinearGradientMode:1
		, BackgroundColorLinearGradientStart:BgColorStart
		, BackgroundColorLinearGradientEnd:BgColorEnd
		, BackgroundColorLinearGradientAngle:0
		, BackgroundColorLinearGradientMode:8
		, FontStyle:FontStyle
		, FontSize:(FontSize<20?40-FontSize:FontSize)
		, Font:FontName }

	Style2 := {Border:Border
		, Rounded:IsRounded?Round:0
		, Margin:Margin
		, BorderColor:BorderColor
		, BorderColorLinearGradientStart:BorderColorStart
		, BorderColorLinearGradientEnd:BorderColorEnd
		, BorderColorLinearGradientAngle:45
		, BorderColorLinearGradientMode:1
		, TextColor:TextColor
		, TextColorLinearGradientStart:TextColorStart
		, TextColorLinearGradientEnd:TextColorEnd
		, TextColorLinearGradientAngle:80
		, TextColorLinearGradientMode:1
		, BackgroundColorLinearGradientStart:BgColorStart
		, BackgroundColorLinearGradientEnd:BgColorEnd
		, BackgroundColorLinearGradientAngle:0
		, BackgroundColorLinearGradientMode:8
		, FontStyle:"bold"
		, FontSize:15
		, Font:FontName }

	Style4 := {Border:Border
		, Rounded:IsRounded?Round:0
		, Margin:Margin
		, BorderColor:BorderColor
		, BorderColorLinearGradientStart:BorderColorStart
		, BorderColorLinearGradientEnd:BorderColorEnd
		, BorderColorLinearGradientAngle:45
		, BorderColorLinearGradientMode:1
		, TextColor:TextColor
		, TextColorLinearGradientStart:TextColorStart
		, TextColorLinearGradientEnd:TextColorEnd
		, TextColorLinearGradientAngle:80
		, TextColorLinearGradientMode:1
		, BackgroundColorLinearGradientStart:BgColorStart
		, BackgroundColorLinearGradientEnd:BgColorEnd
		, BackgroundColorLinearGradientAngle:0
		, BackgroundColorLinearGradientMode:8
		, FontStyle:FontStyle
		, FontSize:FontSize-4
		, Font:FontName }

	style6:={Border:Border
		, Rounded:IsRounded?Round:0
		, Margin:Margin
		, BorderColorLinearGradientStart:BorderColorStart
		, BorderColorLinearGradientEnd:BorderColorEnd
		, BorderColorLinearGradientAngle:45
		, BorderColorLinearGradientMode:1
		, TextColorLinearGradientStart:TextColorStart
		, TextColorLinearGradientEnd:TextColorEnd
		, TextColorLinearGradientAngle:70
		, TextColorLinearGradientMode:1
		, BackgroundColorLinearGradientStart:BgColorStart
		, BackgroundColorLinearGradientEnd:BgColorEnd
		, BackgroundColorLinearGradientAngle:0
		, BackgroundColorLinearGradientMode:8
		, FontStyle:FontStyle
		, FontSize:FontSize+8
		, Font:FontName }

Return

searchWubi:
	Gosub SetGdiStyle
	Try
	{
		if (A_PtrSize>4){
			if (InStr(A_PriorHotkey,"RButton")&&GetClipText) {
				ClipText:=GetClipText
				Gosub MatchCaretText
			}else{
				If ClipText:=WinClipFunc("",0,1) {
						Gosub MatchCaretText
				}else{
					if ClipText:=WinClipFunc()
						Gosub MatchCaretText
					Else
						Return
				}
			}
		}Else{
			If ClipText:=WinClipFunc() {
					Gosub MatchCaretText
			}Else
				Return
		}
	}Catch e{
		MsgBox,262160,Error,% (e.Extra?e.Extra:"获取光标内容失败！")
	}
Return

rlk_label:
	ttpos_1:=[],ttpos_2:=[],ttpos_3:=[],WubiInfo:=""
	if (!WubiInfo&&!Select_Color_Mode){
		ToolTip(1,""),btt( "",,,1),btt( "",,,2),btt("",,,4),btt("",,,5),btt("",,,6),EmptyMem()
	}
	Goto searchWubi
Return

Toggle_rlk:
	IsRlk:=TipIni.Settings["IsRlk"]:=!IsRlk,TipIni.save()
	if IsWarning {
		Gosub DeskTopTip
	}else{
		if IsRlk
			TrayTip,五笔反查助手,五笔反查已开启,,1
		Else
			TrayTip,五笔反查助手,五笔反查已关闭,,2
	}
	GuiControl,Setting:,toggle_Isrlk,%IsRlk%
	Menu,Tray,ToggleCheck,鼠标划选
Return

Format_hotkey(hk){
	hk:=RegExReplace(hk,"\+","Shift+")
	hk:=RegExReplace(hk,"\^","Ctrl+")
	hk:=RegExReplace(hk,"\!","Alt+")
	hk:=RegExReplace(hk,"\#","Win+")
	hk:=RegExReplace(hk,"\<","L")
	hk:=RegExReplace(hk,"\>","R")

	Return hk
}

Format_hotkey2(hk){
	hk:=RegExReplace(hk,"\s+"),keylist:=""
	if (Index:=objCount(tarr:=StrSplit(hk,"+")))&&hk~="[^\!\+\#\<\>]\+[^\!\+\#\<\>]"{
		Loop,% Index
		{
			Switch tarr[A_Index]
			{
				Case "LCtrl","RCtrl","LControl","RControl","Ctrl","Control":
					keylist.=Index>A_Index?(InStr(tarr[A_Index],"LC")?"<^":InStr(tarr[A_Index],"RC")?">^":"^"):tarr[A_Index]
				Case "LShift","RShift","Shift":
					keylist.=Index>A_Index?(InStr(tarr[A_Index],"LS")?"<+":InStr(tarr[A_Index],"RS")?">+":"+"):tarr[A_Index]
				Case "LAlt","RAlt","Alt":
					keylist.=Index>A_Index?(InStr(tarr[A_Index],"LA")?"<!":InStr(tarr[A_Index],"RA")?">!":"!"):tarr[A_Index]
				Case "LWin","RWin","Win":
					keylist.=Index>A_Index?(InStr(tarr[A_Index],"LW")?"<#":InStr(tarr[A_Index],"RW")?">#":"<#"):tarr[A_Index]
				Default:
					keylist.=tarr[A_Index]
			}
		}
		Return keylist
	}

	Return hk
}

FormatColor(Color){
	if InStr(Color,"0x"){
		Switch StrLen(Color)
		{
			case 3:
				Return "0xff00000" . SubStr(Color,3)
			case 4:
				Return "0xff0000" . SubStr(Color,3)
			case 5:
				Return "0xff000" . SubStr(Color,3)
			case 6:
				Return "0xff00" . SubStr(Color,3)
			case 7:
				Return "0xff0" . SubStr(Color,3)
			case 8:
				Return "0xff" . SubStr(Color,3)
			Default :
				Return Color
		}
	}
}
;色值深浅色判断
GetgrayLevel(Color){
	HEX:=HexToRGB(Color,"Parse"),arr:=strsplit(HEX,",")
	If (objCount(arr)>2)
		Return arr[1] * 0.299 + arr[2] * 0.587 + arr[3] * 0.114
	Return 0
}

HexToRGB(Color, Mode="") ; Input: 6 characters HEX-color. Mode can be RGB, Message (R: x, G: y, B: z) or parse (R,G,B)
{
	; If df, d is *16 and f is *1. Thus, Rx = R*16 while Rn = R*1
	Color:=regexreplace(Color,"^(0x|0X|#)")
	Rx := SubStr(Color, 1,1), Rn := SubStr(Color, 2,1)
	Gx := SubStr(Color, 3,1), Gn := SubStr(Color, 4,1)
	Bx := SubStr(Color, 5,1), Bn := SubStr(Color, 6,1)
	AllVars := "Rx|Rn|Gx|Gn|Bx|Bn"
	Loop, Parse, Allvars, | ; Add the Hex values (A - F)
	{
		StringReplace, %A_LoopField%, %A_LoopField%, a, 10
		StringReplace, %A_LoopField%, %A_LoopField%, b, 11
		StringReplace, %A_LoopField%, %A_LoopField%, c, 12
		StringReplace, %A_LoopField%, %A_LoopField%, d, 13
		StringReplace, %A_LoopField%, %A_LoopField%, e, 14
		StringReplace, %A_LoopField%, %A_LoopField%, f, 15
	}
	R := Rx*16+Rn, G := Gx*16+Gn, B := Bx*16+Bn
	If (Mode = "Message") ; Returns "R: 255 G: 255 B: 255"
		Out := "R:" . R . " G:" . G . " B:" . B
	else if (Mode = "Parse") ; Returns "255,255,255"
		Out := R . "," . G . "," . B
	else
		Out := R . G . B ; Returns 255255255
	return Out
}
;文件读取并格式化CRLF
GetFileContent(FilePath,Encoding="UTF-8"){
	If FileExist(FilePath){
		FileEncoding,%Encoding%
		FileRead,chars,%FilePath%
		chars:=RegExReplace(RegExReplace(RegExReplace(chars,"`r`n","`r"),"`n","`r"),"`r","`r`n")
		return RegExReplace(chars,"`r`n[\s\t]+`r`n","`r`n")
	}
}

Create_Biao(DB,TableName)
{
	If !TableName
		Return
	DB.Exec("DROP TABLE IF EXISTS " TableName ";")
	DB.Exec("BEGIN TRANSACTION;")
	DB.Exec("CREATE TABLE " TableName " ('cid' INTEGER PRIMARY KEY AUTOINCREMENT,'sino_chars' TEXT,'zigen' TEXT ,'bianma_chars' TEXT,'zhuyin' TEXT);")
	DB.Exec("CREATE INDEX IF NOT EXISTS 'main'.'sy_" TableName "' ON '" TableName "' ('sino_chars');")
	DB.Exec("COMMIT TRANSACTION;VACUUM;")
}
;光标位置获取
GetCaretPos(Byacc:=1){
	Static init
	If (A_CaretX=""){
		Caretx:=Carety:=CaretH:=CaretW:=0
		If (Byacc){
			If (!init)
				init:=DllCall("LoadLibrary","Str","oleacc","Ptr")
			VarSetCapacity(IID,16), idObject:=OBJID_CARET:=0xFFFFFFF8
			, NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0, IID, "Int64")
			, NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81, IID, 8, "Int64")
			If (DllCall("oleacc\AccessibleObjectFromWindow", "Ptr",Hwnd:=WinExist("A"), "UInt",idObject, "Ptr",&IID, "Ptr*",pacc)=0){
				Acc:=ComObject(9,pacc,1), ObjAddRef(pacc)
				Try Acc.accLocation(ComObj(0x4003,&x:=0), ComObj(0x4003,&y:=0), ComObj(0x4003,&w:=0), ComObj(0x4003,&h:=0), ChildId:=0)
				, CaretX:=NumGet(x,0,"int"), CaretY:=NumGet(y,0,"int"), CaretH:=NumGet(h,0,"int")
			}
		}
		If (Caretx=0&&Carety=0){
			MouseGetPos, x, y
			Return {x:x,y:y,h:35,t:"Mouse",Hwnd:Hwnd}
		} Else
			Return {x:Caretx,y:Carety,h:Max(Careth,35),t:"Acc",Hwnd:Hwnd}
	} Else
		Return {x:A_CaretX,y:A_CaretY,h:35,t:"Caret",Hwnd:Hwnd}
}

;剪切板操作
WinClipFunc(value:="",Paste:=0,Type=0){  ;Paste-->0&&value置空：重复,Paste-->1&&value赋值：粘贴
	if (Type){
		if !Clipboard {
			WinClip.SetText("  ")
			ClipWait
		}
		WinClip.Snap( ClipSaved )
		Sleep,50
		WinClip.Clear()
		if !Paste {
			Sleep,50
			WinClip.Copy(1,0)
			Chars:=WinClip.GetText()
			WinClip.Restore( ClipSaved )
			Return Chars
		}else{
			Sleep,50
			WinClip.SetText(value)
			WinClip.Paste()
			WinClip.Restore( ClipSaved )
			Return 1
		}
	}else{
		if !Clipboard {
			Clipboard:="`r`n"
		}
		ClipChars:=""
		ClipAllSaved:=ClipboardAll
		Clipboard := ""
		SendInput, ^c
		ClipWait
		ClipChars:=Clipboard
		Clipboard:=ClipAllSaved

		Return ClipChars
	}
}

EmptyMem(PID=""){
	pid:=!PID ? DllCall("GetCurrentProcessId") : pid
	h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
	DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
	DllCall("CloseHandle", "Int", h)
}

IsWithBOM(ByRef String){
	if (0xBFBBEF=NumGet(&String,"UInt") & 0xFFFFFF) ;UTF-8
		return "UTF-8"
	else if (0xFEFF=NumGet(&String,"UShort"))  ;UTF-16LE
		return "UTF-16LE"
	else return 0
}

NoBOM(ByRef String){
	if (0xBFBBEF=NumGet(&String,"UInt") & 0xFFFFFF)
		return String:=StrGet(&String+3,"UTF-8")
	else if (0xFFFE=NumGet(&String,"UShort") || 0xFEFF=NumGet(&String,"UShort"))
		return String:=SubStr(&String+2,"UTF-16")
	else return String
}

GetFileBOM(FilePath,ByRef Encoding){
	FileRead,text,*c %FilePath%
	If (0xBFBBEF=NumGet(&text,"UInt") & 0xFFFFFF){
		Encoding:= "UTF-8" 
	}else If (0xFEFF=NumGet(&text,"UShort") ){   ;UTF-16 LE with BOM
		Encoding:= "UTF-16"
	}
}
;打开目录并定位至指定文件
OpenAndSelect(sFullPath){
	SplitPath sFullPath, , sPath, ext, name_no_ext
	FolderPidl := DllCall("shell32\ILCreateFromPath", "Str", sPath)
	DllCall("shell32\SHParseDisplayName", "str", sFullPath, "Ptr", 0, "Ptr*", ItemPidl := 0, "Uint", 0, "Uint*", 0)
	DllCall("shell32\SHOpenFolderAndSelectItems", "Ptr", FolderPidl, "UInt", 1, "Ptr*", ItemPidl, "Int", 0)
	CoTaskMemFree(FolderPidl)
	if name_no_ext
		CoTaskMemFree(ItemPidl)
}

CoTaskMemFree(pv) {
	Return DllCall("ole32\CoTaskMemFree", "Ptr", pv)
}
;分割字符串为数组
GetCharsPhrase(chars,S=""){  ;S不为空时用指定连接符S穿插字符串
	if (S<>"") {
		Result:="", index:=1
		While index:=RegExMatch(chars, "O).", match, index)
			Result.=match.Value . S, index+=match.Len

		Return RTrim(Result,S)
	}Else{
		tarr:=[], index:=1
		While index:=RegExMatch(chars, "O).", match, index)
			tarr.Push(match.Value), index+=match.Len

		return tarr
	}
}

;设置Button背景色
SetButtonColor(ControlID, Color,HWND_:="Setting", Margins:=3){
	GuiControlGet, hwnd, %HWND_%:Hwnd, %ControlID%
	VarSetCapacity(RECT, 16, 0), DllCall("User32.dll\GetClientRect", "Ptr", hwnd, "Ptr", &RECT)
	W := NumGet(RECT, 8, "Int") - (Margins * 1.5), H := NumGet(RECT, 12, "Int") - (Margins * 1.5)

	Color:=((Color&0xFF)<<16)+(Color&0xFF00)+((Color>>16)&0xFF)
	hbm:=CreateDIBSection(W, H), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
	hBrush:=DllCall("CreateSolidBrush", "UInt", Color, "UPtr"), obh:=SelectObject(hdc, hBrush)
	DllCall("Rectangle", "UPtr", hdc, "Int", 0, "Int", 0, "Int", W, "Int", H), SelectObject(hdc, obm)
	BUTTON_IMAGELIST_ALIGN_CENTER := 4, BS_BITMAP := 0x0080, BCM_SETIMAGELIST := 0x1602, BITSPIXEL := 0xC
	BPP := DllCall("Gdi32.dll\GetDeviceCaps", "Ptr", hdc, "Int", BITSPIXEL)
	HIL := DllCall("Comctl32.dll\ImageList_Create", "UInt", W, "UInt", H, "UInt", BPP, "Int", 6, "Int", 0, "Ptr")
	DllCall("Comctl32.dll\ImageList_Add", "Ptr", HIL, "Ptr", hbm, "Ptr", 0)
	; ; Create a BUTTON_IMAGELIST structure
	VarSetCapacity(BIL, 20 + A_PtrSize, 0), NumPut(HIL, BIL, 0, "Ptr")
	Numput(BUTTON_IMAGELIST_ALIGN_CENTER, BIL, A_PtrSize + 16, "UInt")
	SendMessage, BCM_SETIMAGELIST, 0, 0, , ahk_id %HWND%
	SendMessage, BCM_SETIMAGELIST, 0, &BIL, , ahk_id %HWND%
	SelectObject(hdc, obh), DeleteObject(hbm), DeleteObject(hBrush), DeleteDC(hdc)
}
;获取指定位置坐标色值
GetCursorColor(x:="",y:="",w:=1,h:=1){ ;取色
	static pt
	pt?"":(DllCall("GetModuleHandle","str","gdiplus","UPtr"),VarSetCapacity(i,A_PtrSize=8?24:16,0),i:=Chr(1)
		,DllCall("gdiplus\GdiplusStartup","UPtr*",pt,"UPtr",&i,"UPtr",0))
	,(x="")?GetCursorPos(x,y):""
	,d:=DllCall("CreateCompatibleDC","Uint",0),VarSetCapacity(b,40,0),NumPut(w,b,4,"uint")
	,NumPut(h,b,8,"uint"),NumPut(40,b,0,"uint"),NumPut(1,b,12,"ushort"),NumPut(0,b,16,"uInt"),NumPut(32,b,14,"ushort")
	,m:=DllCall("CreateDIBSection","UPtr",d,"UPtr",&b,"uint",0,"UPtr*",0,"UPtr",0,"uint",0,"UPtr")
	,o:=DllCall("SelectObject","UPtr",d,"UPtr",m)
	,DllCall("BitBlt","UPtr",d,"int",0,"int",0,"int",w,"int",h,"UPtr",i:=DllCall("GetDC","UPtr",0),"int",x,"int",y,"uint",0x00CC0020)
	,DllCall("ReleaseDC","UPtr",0,"UPtr",i)
	,DllCall("gdiplus\GdipCreateBitmapFromHBITMAP","UPtr",m,"UPtr",Palette,"UPtr*",p)
	,DllCall("SelectObject","UPtr",d,"UPtr",o),DllCall("DeleteObject","UPtr",m)
	,DllCall("DeleteDC","UPtr",i),DllCall("DeleteDC","UPtr",d),VarSetCapacity(t,16)
	,NumPut(0,t,0,"uint"),NumPut(0,t,4,"uint"),NumPut(w,t,8,"uint"),NumPut(h,t,12,"uint")
	,VarSetCapacity(b,16+2*A_PtrSize,0),DllCall("Gdiplus\GdipBitmapLockBits","UPtr",p,"UPtr",&t,"uint",3,"int",0x26200a,"UPtr",&b)
	,e:= NumGet(b,8,"Int"),u:=NumGet(b,16,"UPtr"),r:=A_FormatInteger
	SetFormat,IntegerFast,hex
	if (w>1 or h>1)
	{
		f:=[]
		Loop,%h%
		{
			f[A_Index]:=j:=[],s:=(A_Index-1)*e
			Loop,%w%
				j[A_Index]:=NumGet(u+0,((A_Index-1)*4)+s,"UInt")  & 0x00ffffff ""
		}
	}
	else f:=NumGet(u+0,0,"UInt") & 0x00ffffff  ""
	SetFormat,IntegerFast,%r%
	DllCall("Gdiplus\GdipBitmapUnlockBits","UPtr",p,"UPtr",0)
	DllCall("gdiplus\GdipDisposeImage", "uint", p)
	return f
}
;获取鼠标所在位置坐标
GetCursorPos(byref x,byref y){
	static i:=VarSetCapacity(i,8,0)
	DllCall("GetCursorPos","Ptr",&i),X:=NumGet(i,0,"Int"),y:=NumGet(i,4,"Int")
}

; 调用系统字体选择窗口 
; originally posted by maestrith 
; https://autohotkey.com/board/topic/94083-ahk-11-font-and-color-dialogs/

; to initialize fontObject object (not required):
; ============================================
; fontObject := Object("name","Tahoma","size",14,"color",0xFF0000,"strike",1,"underline",1,"italic",1,"bold",1)

; ==================================================================
; fntName		= name of var to store selected font
; fontObject	= name of var to store fontObject
; hwnd			= parent gui hwnd for modal, leave blank for not modal
; effects		= allow selection of underline / strike out / italic
; ==================================================================
; fontObject output:
;
;	fontObject["str"]	= string to use with AutoHotkey to set GUI values - see examples
;	fontObject["hwnd"]	= handle of the font object to use with SendMessage - see examples
; =================================================================
FontSelect(fontObject:="",hwnd:=0,effects:=1) {
	fontObject := objCount(fontObject) ? fontObject: Object() 
	VarSetCapacity(logfont,60)
	uintVal := DllCall("GetDC","uint",0)
	LogPixels := DllCall("GetDeviceCaps","uint",uintVal,"uint",90)
	Effects := 0x041 + (Effects ? 0x100 : 0)

	fntName := fontObject.HasKey("name") ? fontObject["name"] : ""
	fontBold := fontObject.HasKey("Style") ? InStr(fontObject["bold"],"bold")?"bold":0 : 0
	fontBold := fontBold ? 700 : 400
	fontItalic := fontObject.HasKey("Style") ? InStr(fontObject["italic"],"italic")?"italic":0 : 0
	fontUnderline := fontObject.HasKey("Style") ? InStr(fontObject["underline"],"underline")?"underline":0 : 0
	fontStrikeout := fontObject.HasKey("Style") ? InStr(fontObject["strike"],"strike")?"strike":0 : 0
	fontSize := fontObject.HasKey("size") ? fontObject["size"] : 16
	old_fontsize:= fontSize,old_fontName:=fntName
	fontSize := fontSize ? Floor(fontSize*LogPixels/72) : 16
	c := fontObject.HasKey("color") ? fontObject["color"] : 0
	c1 := Format("0x{:02X}",(c&255)<<16)	; convert RGB colors to BGR for input
	c2 := Format("0x{:02X}",c&65280)
	c3 := Format("0x{:02X}",c>>16)
	fontColor := Format("0x{:06X}",c1|c2|c3)
	fontval := Object(16,fontBold,20,fontItalic,21,fontUnderline,22,fontStrikeout,0,fontSize)

	for a,b in fontval
		NumPut(b,logfont,a)
	
	cap:=VarSetCapacity(choosefont,A_PtrSize=8?103:60,0)
	NumPut(hwnd,choosefont,A_PtrSize)
	offset1 := (A_PtrSize = 8) ? 24 : 12
	offset2 := (A_PtrSize = 8) ? 36 : 20
	offset3 := (A_PtrSize = 4) ? 6 * A_PtrSize : 5 * A_PtrSize

	fontArray := Array([cap,0,"Uint"],[&logfont,offset1,"Uptr"],[effects,offset2,"Uint"],[fontColor,offset3,"Uint"])
	
	for index,value in fontArray
		NumPut(value[1],choosefont,value[2],value[3])
	
	if (A_PtrSize=8) {
		strput(fntName,&logfont+28)
		r := DllCall("comdlg32\ChooseFont","uptr",&CHOOSEFONT,"cdecl")
		fntName := strget(&logfont+28)
	} else {
		strput(fntName,&logfont+28,32,"CP936")
		r := DllCall("comdlg32\ChooseFontA","uptr",&CHOOSEFONT,"cdecl")
		fntName := strget(&logfont+28,32,"CP936")
	}

	if !r
		return false
	
	fontObj := Object("bold",16,"italic",20,"underline",21,"strike",22)
	for a,b in fontObj
		fontObject[a] := NumGet(logfont,b,"UChar")
	fontObject["bold"] := (fontObject["bold"] < 188) ? 0 : 1
	
	c := NumGet(choosefont,A_PtrSize=4?6*A_PtrSize:5*A_PtrSize) ; convert from BGR to RBG for output
	c1 := Format("0x{:02X}",(c&255)<<16)
	c2 := Format("0x{:02X}",c&65280)
	c3 := Format("0x{:02X}",c>>16)
	c := Format("0x{:06X}",c1|c2|c3)
	fontObject["color"] := c
	
	fontObject["size"] := NumGet(choosefont,A_PtrSize=8?32:16,"UInt")//10
	fontHwnd := DllCall("CreateFontIndirect","uptr",&logfont) ; last param "cdecl"
	fontObject["name"] := fntName

	If (!fontHwnd) {
		fontObject := ""
		return 0
	} Else {
		fontObject["hwnd"] := fontHwnd
		b := fontObject["bold"] ? "bold" : ""
		i := fontObject["italic"] ? "italic" : ""
		s := fontObject["strike"] ? "strike" : ""
		c := fontObject["color"] ? "c" fontObject["color"] : ""
		z := fontObject["size"] ? "s" fontObject["size"] : ""
		u := fontObject["underline"] ? "underline" : ""
		fullStr := b "|" i "|" s "|" c "|" z "|" u
		Loop Parse, fullStr, |
			If (A_LoopField) 
				str .= A_LoopField " "
		fontObject["str"] := "norm " Trim(str)
		fontObject["bold"]:=fontObject["bold"]?"bold":"norm"
		fontObject["size"]:=old_fontsize= fontObject["size"]?0:fontObject["size"]
		fontObject["italic"]:=fontObject["italic"]?"italic":0
		fontObject["strike"]:=fontObject["strike"]?"strike":0
		fontObject["underline"]:=fontObject["underline"]?"underline":0
		;MsgBox % "加粗：" fontObject["bold"] "`n斜体：" fontObject["italic"] "`n删除线：" fontObject["strike"] "`n字号：" fontObject["size"] "`n下划线：" fontObject["underline"] "`n字体：" fontObject["name"]

		return fontObject
	}
}
;自定义MsgBox按钮名称
MsgBoxRenBtn(btn1="",btn2="",btn3=""){
	Static sbtn1:="", sbtn2:="", sbtn3:="", i=0
	sbtn1 := btn1, sbtn2 := btn2, sbtn3 := btn3, i=0
	SetTimer, MsgBoxRenBtn, 1
	Return

	MsgBoxRenBtn:
		If (hwnd:=WinActive("ahk_class #32770")) {
			if (sbtn1)
				ControlSetText, Button1, % sbtn1, ahk_id %hwnd%
			if (sbtn2)
				ControlSetText, Button2, % sbtn2, ahk_id %hwnd%
			if (sbtn3)
				ControlSetText, Button3, % sbtn3, ahk_id %hwnd%
			SetTimer, MsgBoxRenBtn, Off
		}
		if (i >= 1000)
			SetTimer, MsgBoxRenBtn, Off
		i++
	Return
}

;载入字体
AddFontResource(FontPath){
	If FileExist(FontPath){
		DllCall("GDI32.DLL\AddFontResource", str, FontPath)
		PostMessage, 0x1D,,,, ahk_id 0xFFFF
		return 1
	}
}
;移除字体
RemoveFontResource(FontPath){
	DllCall("GDI32.DLL\RemoveFontResource", Str, FontPath)
	PostMessage, 0x1D,,,, ahk_id 0xFFFF
}
;图片base64转化为正常图片
Base64Toimage(Base64,outfilepath){
	Local Bytes := 0,Len := StrLen(Base64)
	DllCall( "Crypt32.dll\CryptStringToBinary", "Str",Base64, "UInt",Len, "UInt",0x1, "UInt",0, "UIntP",Bytes, "Int",0, "Int",0 )	; CRYPT_STRING_BASE64 := 0x1
	VarSetCapacity( Bin, 128 ), VarSetCapacity( Bin, 0 ), VarSetCapacity( Bin, Bytes, 0 )
	DllCall( "Crypt32.dll\CryptStringToBinary", "Str",Base64, "UInt",Len, "UInt",0x1, "Ptr",&Bin, "UIntP",Bytes, "Int",0, "Int",0 )
	File := FileOpen(outfilepath, "w")
	File.RawWrite(Bin, Bytes)
	File.Close()
}

;英文转小写， T首字母
StringLower(ByRef InputVar, T = "")
{
	StringLower, InputVar, InputVar, %T%
	return InputVar
}
 
;英文转大写， T首字母
StringUpper(ByRef InputVar, T = "")
{
	StringUpper, InputVar, InputVar, %T%
	return InputVar
}
;统计文件内容或字段的行数
CountLines(file){ 
	If FileExist(file){
		FileRead, Text, %file%
	}else{
		Text:=file
	}
	if !text {
		Return 0
	}
	StringReplace, Text, Text, `n, `n, UseErrorLevel
	Text:=""
	Return ErrorLevel + 1
}
;根据坐标取色
GetColor(x,y,Type:="Screen"){   ;Screen: 坐标相对于桌面(整个屏幕)、Relative: 坐标相对于活动窗口、Window: 与 Relative 效果相同, 但由于含义清晰, 因此建议使用、Client: 坐标相对于活动窗口的工作区, 其中不包括标题栏, 菜单栏(如果它含有标准菜单栏) 和边框. Client 坐标模式较少依赖于操作系统版本和主题.
	CoordMode, Pixel , %Type%
	PixelGetColor, color, x, y, RGB
	StringRight color,color,10 ;
	return color
}
;;根据进程文件名获取进程信息列表
GetProcessNameList(ProcessName:=""){
	list:="",tarr:=[]
	s := 10240  ; 缓存和数组的大小(4 KB)

	Process, Exist  ; 设置 ErrorLevel 为这个正在运行脚本的 PID.
	; 使用 PROCESS_QUERY_INFORMATION(0x0400) 获取此脚本的句柄:
	h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel, "Ptr")
	; 打开此进程的可调整的访问令牌(TOKEN_ADJUST_PRIVILEGES = 32):
	DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t)
	VarSetCapacity(ti, 16, 0)  ; 特权结构
	NumPut(1, ti, 0, "UInt")  ; 特权数组中的一个条目...
	; 获取调试特权的本地唯一标识符:
	DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
	NumPut(luid, ti, 4, "Int64")
	NumPut(2, ti, 12, "UInt")  ; 启用这个特权: SE_PRIVILEGE_ENABLED = 2
	; 使用新的访问令牌更新此进程的特权:
	r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
	DllCall("CloseHandle", "Ptr", t)  ; 关闭此访问令牌句柄以节约内存.
	DllCall("CloseHandle", "Ptr", h)  ; 关闭此进程句柄以节约内存.

	hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; 通过预加载来提升性能.
	s := VarSetCapacity(a, s)  ; 接收进程列表标识符的数组:

	DllCall("Psapi.dll\EnumProcesses", "Ptr", &a, "UInt", s, "UIntP", r)
	Loop, % r // 4  ; 把数组解析为 DWORD(32 位) 的标识符:
	{
		id := NumGet(a, A_Index * 4, "UInt")
		; 打开进程: PROCESS_VM_READ(0x0010) | PROCESS_QUERY_INFORMATION(0x0400)
		h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id, "Ptr")
		if !h
			continue
		VarSetCapacity(n, s, 0)  ; 接收模块基础名称的缓存:
		e := DllCall("Psapi.dll\GetModuleBaseName", "Ptr", h, "Ptr", 0, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
		if !e    ;  用于 64 位进程在 32 位模式时的回退方法:
			if e := DllCall("Psapi.dll\GetProcessImageFileName", "Ptr", h, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
				SplitPath n, n
		DllCall("CloseHandle", "Ptr", h)  ; 关闭进程句柄以节约内存
		if (n && e){  ; 如果映像不是空的, 则添加到列表:
			If (ProcessName&&ProcessName=n)
				tarr.push([n,id])
			else
				list.=n "/" id "|"
		}
	}
	DllCall("FreeLibrary", "Ptr", hModule)  ; 卸载库来释放内存.

	return !ProcessName?list:tarr
}

GetProcessInfo(exename,type:="ExecutablePath") {
	/*
	class Win32_Process : CIM_Process
	{
		string   CreationClassName;	创建类的名称
		string   Caption;	进程标题
		string   CommandLine;	进程的命令行
		datetime CreationDate;	创建日期
		string   CSCreationClassName;
		string   CSName;
		string   Description;	显示进程说明
		string   ExecutablePath;	可执行路径
		uint16   ExecutionState;	执行状态
		string   Handle;	句柄
		uint32   HandleCount;	句柄统计
		datetime InstallDate;	安装日期
		uint64   KernelModeTime;	内核调节时间
		uint32   MaximumWorkingSetSize;
		uint32   MinimumWorkingSetSize;
		string   Name;	进程名
		string   OSCreationClassName;	系统创建类名
		string   OSName;	系统名
		uint64   OtherOperationCount;
		uint64   OtherTransferCount;
		uint32   PageFaults;	页面默认值
		uint32   PageFileUsage;
		uint32   ParentProcessId;
		uint32   PeakPageFileUsage;
		uint64   PeakVirtualSize;
		uint32   PeakWorkingSetSize;
		uint32   Priority = NULL;
		uint64   PrivatePageCount;
		uint32   ProcessId;	进程ID
		uint32   QuotaNonPagedPoolUsage;
		uint32   QuotaPagedPoolUsage;
		uint32   QuotaPeakNonPagedPoolUsage;
		uint32   QuotaPeakPagedPoolUsage;
		uint64   ReadOperationCount;
		uint64   ReadTransferCount;
		uint32   SessionId;	会话的唯一标识符
		string   Status;	状态值
		datetime TerminationDate;	终止日期
		uint32   ThreadCount;	线程计数
		uint64   UserModeTime;	用户模式时间
		uint64   VirtualSize;	虚拟化大小
		string   WindowsVersion;
		uint64   WorkingSetSize;
		uint64   WriteOperationCount;
		uint64   WriteTransferCount;
	};
	*/
	for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process where name ='" exename "'")
		return process[type]
}

/*
	FileDescription	文件描述说明
	FileVersion	文件版本
	InternalName	内部名称
	LegalCopyright	法律版权所有
	OriginalFilename	创建文件时所使用的名称
	ProductName	产品名称
	ProductVersion	产品版本
	CompanyName	企业名称
	PrivateBuild	私有版本的信息
	SpecialBuild	特殊内部版本信息
	LegalTrademarks	文件的商标和注册商标
*/
FileGetInfo(FilePath:="", p*) {   ; Written by SKAN, modified by HotKeyIt	; www.autohotkey.com/forum/viewtopic.php?p=233188#233188  CD:24-Nov-2008 / LM:27-Oct-2010
	static DLL:="Version\GetFileVersion"
	If ! FSz := DllCall( DLL "InfoSize" (A_IsUnicode ? "W" : "A"), "Str",FilePath, "UInt",0 )
		Return DllCall( "SetLastError", UInt,1 ),""
	VarSetCapacity( FVI, FSz, 0 ),DllCall( DLL "Info" ( A_IsUnicode ? "W" : "A"), "Str",FilePath, "UInt",0, "UInt",FSz, "PTR",&FVI )
	If !DllCall( "Version\VerQueryValue" (A_IsUnicode ? "W" : "A"), "PTR",&FVI, "Str","\VarFileInfo\Translation", "PTR*",Transl, "PTR",0 )
		Return DllCall( "SetLastError", UInt,2 ),""
	If !Trans:=format("{1:.8X}",NumGet(Transl+0,"UInt"))
		Return DllCall( "SetLastError", UInt,3),""
	for k,v in p
	{
		subBlock := "\StringFileInfo\" SubStr(Trans,-3) SubStr(Trans,1,4) "\" v
		If ! DllCall( "Version\VerQueryValue" ( A_IsUnicode ? "W" : "A"), "PTR",&FVI, "Str",SubBlock, "PTR*",InfoPtr, "UInt",0 )
			continue
		If Value := StrGet( InfoPtr )
			Info .= p.MaxIndex()=1?Value:SubStr( v "                        ",1,24 ) . A_Tab . Value . "`n"
	}
	Info:=RTrim(Info,"`n")

	Return Info
}

Tray_Refresh() {
/*		Remove any dead icon from the tray menu
 *		Should work both for W7 & W10
 */
	WM_MOUSEMOVE := 0x200
	detectHiddenWin := A_DetectHiddenWindows
	DetectHiddenWindows, On
	allTitles := ["ahk_class Shell_TrayWnd"
			, "ahk_class NotifyIconOverflowWindow"]
	allControls := ["ToolbarWindow321"
				,"ToolbarWindow322"
				,"ToolbarWindow323"
				,"ToolbarWindow324"]
	allIconSizes := [24,32]

	for id, title in allTitles {
		for id, controlName in allControls
		{
			for id, iconSize in allIconSizes
			{
				ControlGetPos, xTray,yTray,wdTray,htTray,% controlName,% title
				y := htTray - 10
				While (y > 0)
				{
					x := wdTray - iconSize/2
					While (x > 0)
					{
						point := (y << 16) + x
						PostMessage,% WM_MOUSEMOVE, 0,% point,% controlName,% title
						x -= iconSize/2
					}
					y -= iconSize/2
				}
			}
		}
	}

	DetectHiddenWindows, %detectHiddenWin%
}
;获取系统计划任务自启列表
GetTaskInfos() {
	objService := ComObjCreate("Schedule.Service")
	objService.Connect()
	rootFolder := objService.GetFolder("\")
	taskCollection := rootFolder.GetTasks(0)
	numberOfTasks := taskCollection.Count
	; ?RegistrationInfo.Author
	For registeredTask, state in taskCollection
	{
		if (registeredTask.state == 0)
			state:= "Unknown"
		else if (registeredTask.state == 1)
			state:= "Disabled"
		else if (registeredTask.state == 2)
			state:= "Queued"
		else if (registeredTask.state == 3)
			state:= "Ready"
		else if (registeredTask.state == 4)
			state:= "Running"
		tasklist .= registeredTask.Name "=" state "=" registeredTask.state "`n"
	}
	return RTrim(tasklist,"`n")
}
;判断是否自启
IsAutorunEnabled(TaskName)
{
	objService := ComObjCreate("Schedule.Service") 
	objService.Connect()
	objFolder := objService.GetFolder("\")
	Try {
		RunAsTask := objFolder.GetTask( TaskName )
		return  ! A_LastError 
	}Catch
		Return ""
}
;取消自启
DisableAutorun(TaskName){
	objService := ComObjCreate("Schedule.Service") 
	objService.Connect()
	objFolder := objService.GetFolder("\")
	Try {
		objFolder.DeleteTask(TaskName, 0)
		Return !A_LastError
	}Catch
		Return ""
}
;根据自启任务名获取自启文件长路径
GetTaskActionExecPaths(taskName, folderPath := "\") {
	service := ComObjCreate("Schedule.Service")
	service.Connect()
	Try {
		Paths:=[]
		for action in service.GetFolder(folderPath).GetTask(taskName).Definition.Actions
			if (action.Type ==0)
				Paths.Push([RegExReplace(action.Path,"[\""""]"),RegExReplace(action.Arguments,"[\""""]")])
		Return Paths
	}Catch
		Return []
}
;设置自启
EnableAutoRun(taskName:="五笔反查助手 (Run As Task)",DescriptionInfo:="王码五笔鼠标划选反查工具",TaskState=3)
{
	TaskExists := IsAutorunEnabled(taskName)
	if (A_IsAdmin and TaskExists) {
		if DisableAutorun(TaskName)
			Return 1
	}else If ( not A_IsAdmin and TaskExists ) {
		Return ""
	}else If ( not A_IsAdmin and not TaskExists ){
		Return ""
	}else If ( A_IsAdmin and not TaskExists ) {
		TriggerType = 9   ; trigger on logon. 
		ActionTypeExec = 0  ; specifies an executable action. 
		TaskCreateOrUpdate = 6 
		Task_Runlevel_Highest = 1 

		objService := ComObjCreate("Schedule.Service") 
		objService.Connect() 

		objFolder := objService.GetFolder("\") 
		objTaskDefinition := objService.NewTask(0) 

		principal := objTaskDefinition.Principal 
		principal.LogonType := 1    ; Set the logon type to TASK_LOGON_PASSWORD 
		principal.RunLevel := Task_Runlevel_Highest  ; Tasks will be run with the highest privileges. 

		colTasks := objTaskDefinition.Triggers 
		objTrigger := colTasks.Create(TriggerType) 
		colActions := objTaskDefinition.Actions 
		objAction := colActions.Create(ActionTypeExec) 
		objAction.ID := "Autorun" 
		if(A_IsCompiled)
			objAction.Path := """" A_ScriptFullPath """"
		else
		{
			objAction.Path := """" A_AhkPath """"
			objAction.Arguments := """" A_ScriptFullPath """"
		}
		objAction.WorkingDirectory := A_ScriptDir
		objInfo := objTaskDefinition.RegistrationInfo 
		objInfo.Author := A_UserName 
		objInfo.Description := DescriptionInfo
		objSettings := objTaskDefinition.Settings 
		objSettings.Enabled := True 
		objSettings.Hidden := False 
		objSettings.StartWhenAvailable := True 
		objSettings.ExecutionTimeLimit := "PT0S"
		objSettings.DisallowStartIfOnBatteries := False
		objSettings.StopIfGoingOnBatteries := False
		objFolder.RegisterTaskDefinition(taskName, objTaskDefinition, TaskCreateOrUpdate , "", "", TaskState ) 
		if IsAutorunEnabled(taskName)
			Return taskName
	}
}

;;;根据进程文件名获取托盘图标信息列表，以判断托盘图标是否正常显示
TrayIcon_GetInfo(sExeName := "")
{
	d := A_DetectHiddenWindows
	DetectHiddenWindows, On
 
	oTrayInfo := []
	For key,sTray in ["Shell_TrayWnd", "NotifyIconOverflowWindow"]
	{
		idxTB := TrayIcon_GetTrayBar(sTray)
		WinGet, pidTaskbar, PID, ahk_class %sTray%
		
		hProc := DllCall("OpenProcess",	UInt,0x38, Int,0, UInt,pidTaskbar)
		pRB   := DllCall("VirtualAllocEx", Ptr,hProc, Ptr,0, UPtr,20, UInt,0x1000, UInt,0x04)
 
		szBtn := VarSetCapacity(btn, (A_Is64bitOS ? 32 : 20), 0)
		szNfo := VarSetCapacity(nfo, (A_Is64bitOS ? 32 : 24), 0)
		szTip := VarSetCapacity(tip, 128 * 2, 0)
 
		; TB_BUTTONCOUNT = 0x0418
		SendMessage, 0x0418, 0, 0, ToolbarWindow32%idxTB%, ahk_class %sTray%
		Loop, %ErrorLevel%
		{
			 ; TB_GETBUTTON 0x0417
			SendMessage, 0x0417, A_Index-1, pRB, ToolbarWindow32%idxTB%, ahk_class %sTray%
 
			DllCall("ReadProcessMemory", Ptr,hProc, Ptr,pRB, Ptr,&btn, UPtr,szBtn, UPtr,0)
 
			iBitmap := NumGet(btn, 0, "Int")
			idCmd   := NumGet(btn, 4, "Int")
			fsState := NumGet(btn, 8, "UChar")
			fsStyle := NumGet(btn, 9, "UChar")
			dwData  := NumGet(btn, (A_Is64bitOS ? 16 : 12), "UPtr")
			iString := NumGet(btn, (A_Is64bitOS ? 24 : 16), "Ptr")
 
			DllCall("ReadProcessMemory", Ptr,hProc, Ptr,dwData, Ptr,&nfo, UPtr,szNfo, UPtr,0)
 
			hWnd  := NumGet(nfo, 0, "Ptr")
			uId   := NumGet(nfo, (A_Is64bitOS ?  8 :  4), "UInt")
			msgId := NumGet(nfo, (A_Is64bitOS ? 12 :  8), "UPtr")
			hIcon := NumGet(nfo, (A_Is64bitOS ? 24 : 20), "Ptr")
 
			WinGet, nPid, PID, ahk_id %hWnd%
			WinGet, sProcess, ProcessName, ahk_id %hWnd%
			WinGetClass, sClass, ahk_id %hWnd%
 
			If ( !sExeName || sExeName == sProcess || sExeName == nPid )
			{
				DllCall("ReadProcessMemory", Ptr,hProc, Ptr,iString, Ptr,&tip, UPtr,szTip, UPtr,0)
				oTrayInfo.Push({ "idx"	 : A_Index-1
							   , "idcmd"   : idCmd
							   , "pid"	 : nPid
							   , "uid"	 : uId
							   , "msgid"   : msgId
							   , "hicon"   : hIcon
							   , "hwnd"	: hWnd
							   , "class"   : sClass
							   , "process" : sProcess
							   , "tooltip" : StrGet(&tip, "UTF-16")
							   , "tray"	: sTray })
			}
		}
		DllCall("VirtualFreeEx", Ptr,hProc, Ptr,pRB, UPtr,0, UInt,0x8000)
		DllCall("CloseHandle",   Ptr,hProc)
	}
	DetectHiddenWindows, %d%
	Return oTrayInfo
}

TrayIcon_GetTrayBar(sTray:="Shell_TrayWnd")
{
	d := A_DetectHiddenWindows
	DetectHiddenWindows, On
	WinGet, ControlList, ControlList, ahk_class %sTray%
	RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", nTB)
	Loop, %nTB%
	{
		ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class %sTray%
		hParent := DllCall( "GetParent", Ptr, hWnd )
		WinGetClass, sClass, ahk_id %hParent%
		If !(sClass == "SysPager" || sClass == "NotifyIconOverflowWindow" )
			Continue
		idxTB := A_Index
		Break
	}
	DetectHiddenWindows, %d%
	Return idxTB
}

GetFontList(){
	static fontlist:=""
	If (fontlist)
		Return fontlist
	VarSetCapacity(logfont, 128, 0), NumPut(1, logfont, 23, "UChar")
	obj := []
	DllCall("EnumFontFamiliesEx", "ptr", DllCall("GetDC", "ptr", 0), "ptr", &logfont, "ptr", RegisterCallback("EnumFontProc"), "ptr", &obj, "uint", 0)
	For font in obj
		fontlist .= "|" font
	fontlist:=LTrim(fontlist,"|")
	Return fontlist
}

EnumFontProc(lpFont, tm, TextFont, lParam){
	obj := Object(lParam)
	If (TextFont>1&&!InStr(font:=StrGet(lpFont+28), "@"))
		obj[font] := 1
	Return 1
}

;;============================================================================================
Fct_MenuContext_Separator() {
	Return { Type: MenuContext_Separator }
}

Fct_MenuContext_Item( Name ) {
	Return { Type: MenuContext_Item, Name: Name }
}

Fct_MenuContext_Submenu( Name, ArraySubitems ) {
	Return { Type: MenuContext_SubMenu, Name: Name, Items: ArraySubitems }
}


; Writed by  Nico.Godvician  /  Code Opensource - CC: BY-NC-SA 2.0  –> Copy thsee lines
; Pubished:  2019/09/21 –> https://www.autohotkey.com/boards/viewtopic.php?f=76&t=38579&p=291014#p290862
; Function that add the items to the context menu, and return the clicked item
;*********************************************************************************************************
Fct_Get_ClickedItem_MenuContext_AddedItems( TargetProgram_Classes, InsertItemsAt_Position, ArrayOf_Items*) 
;**********************************************************************************************************
{
	Global IsInsertMenu,IsRlk,GetClipText

	; Get handle of the target program:
	For each, ProgramClass in TargetProgram_Classes 
	{
		; Handle of active window:
		If Program_Handle := WinActive( "ahk_class " ProgramClass ) ; Handle return false if class it's not active
			Break ; Program is active, then OK
	} ; Or not if the loop ( for each ) is finished
	
	; Check we are really in the right active program:
	If not Program_Handle ; False or Handle
		Return "-> Not into the right program <-"	
	
	; Class #32768 is for all standard windows context menu:
	Global MenuContext_AhkClass := "ahk_class #32768" 
	
	; Wait context menu appears:
	WinWait, %MenuContext_AhkClass% ;
	
	; Context menu opened –> Get handle:
	MN_GETHMENU := 0x1E1 ; Shell Constant: "Menu_GetHandleMenu"
	SendMessage, MN_GETHMENU, False, False 
	MenuContext_Handle := ErrorLevel ; Return Handle in ErrorLevel
	ItemCount:=Menu_GetItemCount(MenuContext_Handle)
	InsertItemsAt_Position:= ItemCount>8?Floor(ItemCount/2):InsertItemsAt_Position
	if (ItemCount&&!IsInsertMenu) {
		for key,Item In ArrayOf_Items
		{
			if (Item.Name) {
				if !ItemPos
					ItemPos:=Menu_GetItemPos(MenuContext_Handle,Item.Name)
				Menu_RemoveItemByName(MenuContext_Handle,Item.Name)
			}else{
				
				Menu_RemoveItemByItemPos(MenuContext_Handle,ItemPos)
			}
		}
		;;;DllCall("User32.dll\RemoveMenu", "Ptr", MenuContext_Handle, "UInt", ItemPos-1, "UInt",0x0400)
		Return False
	}
	for key,Item In ArrayOf_Items
	{
		if ( Item.Name&&MenuContext_Handle&&Menu_GetItemPos(MenuContext_Handle, Item.Name)){
			Return False
		}
	}

	;***************************
	; 	Section: Add Items:
	;***************************
	
	; Constants for menus in User32.dll:
	Static MF_SEPARATOR := 0x800
	Static MF_STRING := 0x0
	Static MF_POPUP := 0x10
	Static MF_BYPOSITION := 0x400 

	Static MF_ENABLED:=0x00000000
	Static MF_GRAYED:=0x00000001
	Static MF_DISABLED:=0x00000002

	; Add each new item into the context menu:
	For each, ItemToAdd in ArrayToAdd_Items :=  ArrayOf_Items
	{
		; Save absolut position of this Item in the menu: 
		ItemToAdd.Position := InsertItemsAt_Position-1 + A_Index-1 ; Zero based
		; Add Separator:
		If ( ItemToAdd.Type == MenuContext_Separator ) 
		{
			; Insert Separator: –> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-InsertMenuA
			DllCall( "User32\InsertMenu"
					,"UPtr", MenuContext_Handle
					,"UInt", ItemToAdd.Position ; At the specified position
					,"UInt", MF_SEPARATOR + MF_BYPOSITION
					,"UPtr", False
					,"UInt", False )
		}
		; Add Classic Item:
		Else If ( ItemToAdd.Type == MenuContext_Item )
		{
			; Insert text of item: –> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-InsertMenuA
			DllCall( "User32\InsertMenu" 
					,"UPtr", MenuContext_Handle
					,"UInt", ItemToAdd.Position ; At the specified position
					,"UInt", MF_STRING + MF_BYPOSITION
					,"UPtr", False 
					,"Str", ItemToAdd.Name ) ; Insert Value ( text )
		}
		; Add Submenu and its Subitems:
		Else If ( ItemToAdd.Type == MenuContext_Submenu )
		{
			AddSubmenu := ItemToAdd ; Renames to clarify
			; Create Submenu, and return handle:
			AddSubmenu.Handle := DllCall( "User32\CreatePopupMenu" ) 
			
			; Insert Submenu into the context menu: –> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-InsertMenuA
			DllCall( "User32\InsertMenu"
					,"UPtr", MenuContext_Handle
					,"UInt", AddSubmenu.Position  ; At the specified position
					,"UInt", MF_STRING + MF_BYPOSITION + MF_POPUP
					,"UPtr", AddSubmenu.Handle
					,"Str", AddSubmenu.Name )
			
			; Now add each Item and Separator into this Submenu:
			For each, ItemOfSubmenu in AddSubmenu.Items 
			{
				; AppendMenu –> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-AppendMenuA
				
				; In case of Separator:
				If ( ItemOfSubmenu == MenuContext_Separator ) 
					DllCall( "User32\AppendMenu"
							,"UPtr", AddSubmenu.Handle
							,"UInt", MF_SEPARATOR
							,"UPtr", False, "UInt", False )
				
				Else  ; In case of Subintem: insert Value as text:
					DllCall( "User32\AppendMenu"
							,"UPtr", AddSubmenu.Handle
							,"UInt", MF_STRING
							,"UPtr", False
							,"Str", ItemOfSubmenu )
			}
		}
		Menu_EnableMenuItem(MenuContext_Handle, Menu_GetItemPos(MenuContext_Handle,ItemToAdd.Name)-1, GetClipText&&Not GetClipText~="[^\x00-\xff]"&&InStr(ItemToAdd.Name,"五笔")?2:0)
		Continue ; Continue to add next item...
	}

	; End for each add items
	;***************************
	; 	Section: Wait Click:
	;***************************
	
	Label_Wait_New_Click: ; When User clicks on Separator: wait new click
	
	; Wait User do a regular or right click:
	While not GetKeyState( "LButton" ) and not GetKeyState( "RButton" ) 
	{
		; Fix error if 2 right clicks are very too close: menu disappears sometimes for some apps:
		If not WinExist( MenuContext_AhkClass ) {
			;;Send {RButton} 	; Reopen context menu when disappears
			Return MenuContext_RightClickAgain ; Refill the menu 
		}
	}
	
	; Is it a right click on another file ? This means that the menu is closed and reopening...
	If GetKeyState( "RButton" )
		Return MenuContext_RightClickAgain ; Then refill the menu
	;TODO: Fix error when the User right-clicks on context menu, it's filled up again

	; Else Yes: Click into an item, but witch item ?
	
	
	;***********************************
	; 	Section: Get Clicked Item:
	;***********************************
	
	; Get position of mouse into screen:
	CoordMode, Mouse, Screen
	MouseGetPos, MouseScreenX, MouseScreenY  ; Int vars: 4 octets
	
	; POINT –> https://docs.microsoft.com/fr-fr/previous-versions/dd162805(v=vs.85)
	; Create a generic C++ POINT{x,y} with a 'ULongLong' –> 'Int64' 
	; X start at the 1st ULong (right), and Y start at 2nd ULong (32th bit on left):
	MousePointScreen := x := MouseScreenX  | y := ( MouseScreenY << 32 ) 
	
	;Calculate DPI of special screen:  1K, 2K, 4K, 8K, etc...
	WinDPIMultiplicator := A_ScreenDPI / 96  ; 96 is the standard DPI screen: 1K (1600x900)
	
	; Check if clicked item is into the new added items:
	For each, AddedItemInMenu in ArrayOfAdded_Items := ArrayOf_Items 
	{
		; Click on Separator –> Disable:
		If ( AddedItemInMenu.Type == MenuContext_Separator )
		{
			; Get Rectangle of Separator:
			VarSetCapacity( ItemRectangle, 16, 0 ) ; Create Rectangle of 16 octets: 4 corners of Int (4 octets)
			
			; Fill Rectangle: –> https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-GetMenuItemRect
			isFilledRectangle := DLLCall( "User32\GetMenuItemRect"
									,"UPtr", Program_Handle
									,"UPtr", MenuContext_Handle
									,"UInt", AddedItemInMenu.Position ; Absolut position in the context menu
									,"UPtr", &ItemRectangle )

			; Is clicked on separator ?
			If isFilledRectangle 
			and isPointIntoRectangle := DllCall( "User32\PtInRect", "UPtr", &ItemRectangle, "Int64", MousePointScreen )
				Goto Label_Wait_New_Click 
		}
		
		; Click on added Item –> Return Value
		Else If ( AddedItemInMenu.Type == MenuContext_Item ) 					
		{
			VarSetCapacity( ItemRectangle, 16, 0 )
			; https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-GetMenuItemRect
			isFilledRectangle := DLLCall( "User32\GetMenuItemRect"  
									,"UPtr", Program_Handle
									,"UPtr", MenuContext_Handle
									,"UInt", AddedItemInMenu.Position 
									,"UPtr", &ItemRectangle )
			If isFilledRectangle 
			and isPointIntoRectangle := DllCall( "User32\PtInRect", "UPtr", &ItemRectangle, "Int64", MousePointScreen ) 
				Return AddedItemInMenu.Name
		}

		; Click on Item of Submenu –> Check each Subitem:
		Else If ( AddedItemInMenu.Type == MenuContext_Submenu )  				
		{
			Loop 3 ; 3 times, because sometimes this function does not work 1 or 2 times:
				For each, ItemInSubmenu in ( ItemIsSubmenu := AddedItemInMenu ).Items 
				{
					ItemPositionInMenu := A_Index
					
					; Get Rectangle for Subitem
					VarSetCapacity( ItemRectangle, 16, 0 ) 
					; https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-GetMenuItemRect
					isFilledRectangle := DLLCall( "User32\GetMenuItemRect"  
											,"UPtr", False ; Indicate Submenu, instead of window
											,"UPtr", ItemIsSubmenu.Handle ; Handle of the Submenu
											,"UInt", ItemPositionInMenu -1 ; Zero based
											,"UPtr", &ItemRectangle )
					
					; Get each corner of Rectangle:
					ItemRectangleX1 := NumGet( &ItemRectangle, 0, "Int" ) ; Int –> 4 octets
					ItemRectangleY1 := NumGet( &ItemRectangle, 4, "Int" )
					ItemRectangleX2 := NumGet( &ItemRectangle, 8, "Int" )
					ItemRectangleY2 := NumGet( &ItemRectangle, 12, "Int" )
					
					; Use DPI multiplicator for special screen (2K, 4K, ...):
					isMouseInto4Corners :=  ( MouseScreenX >= ItemRectangleX1 *WinDPIMultiplicator ) 
									and ( MouseScreenX <= ItemRectangleX2 *WinDPIMultiplicator ) 
									and ( MouseScreenY >= ItemRectangleY1 *WinDPIMultiplicator ) 
									and ( MouseScreenY <= ItemRectangleY2 *WinDPIMultiplicator ) 
					
					;ToolTip % "isFilledRectangle: " isFilledRectangle "`n" "isMouseInto4Corners: " isMouseInto4Corners "`nX: " ItemRectangleX1*WinDPIMultiplicator "<" MouseScreenX ">" ItemRectangleX2*WinDPIMultiplicator "`nY: " ItemRectangleY1*WinDPIMultiplicator "<" MouseScreenY ">" ItemRectangleY2*WinDPIMultiplicator, , , 5
					
					; Check if mouse is into this Rectangle: 
					If isFilledRectangle and isMouseInto4Corners
					{
						; Click on Separator ?
						If ( ItemInSubmenu == MenuContext_Separator ) ; Disable Separator:
							Goto Label_Wait_New_Click ; Wait new click
						
						Else ; Standard text Subitem: 
							Return ItemInSubmenu ; Return value of item
					}
				}
		}
		; End of one item: this is not this item
		Continue ; Then check next item...
	}
	; End: For all the new items, all checked without return
	
	; Then clicked Item is probably on another item of context menu ( like 'Open' ):
	Return MenuContext_NoClicked_AddedItem
}
;End Fct_Get_ClickedItem_MenuContext_AddedItems

Menu_GetItemName(HMENU, ItemPos) {
	; http://msdn.microsoft.com/en-us/library/ms647983(v=vs.85).aspx
	VarSetCapacity(Str, 1024, 0) ; should be sufficient
	If DllCall("User32.dll\GetMenuString", "Ptr", HMENU, "UInt", ItemPos - 1, "Str", Str, "Int", 512, "UInt", 0x0400, "Int")
		Return Str

	Return ""
}

Menu_GetItemState(HMENU, ItemPos) {
	; http://msdn.microsoft.com/en-us/library/ms647982(v=vs.85).aspx
	Return DllCall("User32.dll\GetMenuState", "Ptr", HMENU, "UInt", ItemPos - 1, "UInt", 0x0400, "UInt")
}

Menu_GetItemPos(HMENU, ItemName) {
	Loop, % Menu_GetItemCount(HMENU)
		If (ItemName = Menu_GetItemName(HMENU, A_Index))
			Return A_Index
	Return False
}

Menu_GetItemInfo(HMENU, ItemPos) {
	; http://msdn.microsoft.com/en-us/library/ms647980(v=vs.85).aspx
	Static MIIsize := (4 * 6) + (A_PtrSize * 6) + ((A_PtrSize - 4) * 2)
	Static MIIoffs := (A_PtrSize = 8) ? {Type: 8, State: 12, ID: 16, HMENU: 24, String: 56, cch: 64, HBITMAP: 72}
		: {Type: 8, State: 12, ID: 16, HMENU: 20, String: 36, cch: 40, HBITMAP: 44}
	VarSetCapacity(MII, MIIsize, 0)              ; MENUITEMINFO structure
	NumPut(MIIsize, MII, 0, "UInt")              ; cbSize
	NumPut(0x1EF, MII, 4, "UInt")                ; fMask
	VarSetCapacity(String, 1024, 0)
	NumPut(&String, MII, MIIoffs.String, "UPtr") ; dwTypeData
	NumPut(512, MII, MIIoffs.cch, "UInt")        ; cch
	If DllCall("User32.dll\GetMenuItemInfo", "Ptr", HMENU, "UInt", ItemPos - 1, "UInt", 1, "Ptr", &MII, "UInt")
		Return {Type: NumGet(MII, MIIoffs.Type, "UInt")
			, State: NumGet(MII, MIIoffs.State, "UInt")
			, ID: NumGet(MII, MIIoffs.ID, "UInt")
			, HMENU: NumGet(MII, MIIoffs.HMENU, "UPtr")
			, Name: StrGet(&String, NumGet(MII, MIIoffs.cch, "UInt"))
			, HBITMAP: NumGet(MII, MIIoffs.HBITMAP, "UPtr")}
	Return False
}

Menu_GetItemCount(HMENU) {
	; http://msdn.microsoft.com/en-us/library/ms647978(v=vs.85).aspx
	Return DllCall("User32.dll\GetMenuItemCount", "Ptr", HMENU, "Int")
}

Menu_CheckRadioItem(HMENU, ItemPos, First := 1, Last := 0) {
	; http://msdn.microsoft.com/en-us/library/ms647621(v=vs.85).aspx
	If (Last < 1)
		Last := Menu_GetItemCount(HMENU)

	Return DllCall("User32.dll\CheckMenuRadioItem", "Ptr", HMENU, "UInt", First - 1, "UInt", Last - 1
		, "UInt", ItemPos - 1, "UInt", 0x0400, "UInt")
}

Menu_BarRightJustify(HWND, ItemPos) {
	; http://msdn.microsoft.com/en-us/library/ms648001(v=vs.85).aspx
	Static MIIsize := (4 * 6) + (A_PtrSize * 6) + ((A_PtrSize - 4) * 2)
	If (HMENU := Menu_GetMenu(HWND)) {
		VarSetCapacity(MII, MIIsize, 0)              ; MENUITEMINFO structure
		NumPut(MIIsize, MII, 0, "UInt")              ; cbSize
		NumPut(0x0100, MII, 4, "UInt")               ; fMask: MIIM_FTYPE = 0x0100
		If DllCall("User32.dll\GetMenuItemInfo", "Ptr", HMENU, "UInt", ItemPos - 1, "UInt", 1, "Ptr", &MII, "UInt") {
			NumPut(NumGet(MII, 8, "UInt") | 0x4000, MII, 8, "UInt") ; fType: MFT_RIGHTJUSTIFY = 0x4000
			RC := DllCall("User32.dll\SetMenuItemInfo", "Ptr", HMENU, "UInt", ItemPos - 1, "UInt", 1, "Ptr", &MII, "UInt")
			DllCall("User32.dll\DrawMenuBar", "Ptr", HWND, "UInt")

			Return RC
		}
	}
	Return False
}

Menu_BarHiliteItem(HWND, ItemPos, Hilite := True) {
	; http://msdn.microsoft.com/en-us/library/ms647986(v=vs.85).aspx
	If (HMENU := Menu_GetMenu(HWND)) {
		Flags := 0x0400 | (Hilite ? 0x80 : 0x00)
		Return DllCall("User32.dll\HiliteMenuItem", "Ptr", HWND, "Ptr", HMENU, "UInt", ItemPos - 1, "UInt", Flags, "UInt")
	}
	Return False
}

Menu_GetMenu(HWND) {
	; http://msdn.microsoft.com/en-us/library/ms647640(v=vs.85).aspx
	Return DllCall("User32.dll\GetMenu", "Ptr", HWND, "Ptr")
}

Menu_GetMenuByName(MenuName) {
	Static HMENU := 0
	If !(HMENU) {
		Menu, %A_ThisFunc%Menu, Add
		Menu, %A_ThisFunc%Menu, DeleteAll
		Gui, %A_ThisFunc%GUI:+HwndHGUI
		Gui, %A_ThisFunc%GUI:Menu, %A_ThisFunc%Menu
		HMENU := Menu_GetMenu(HGUI)
		Gui, %A_ThisFunc%GUI:Menu
		Gui, %A_ThisFunc%GUI:Destroy
	}
	If !(HMENU)
		Return 0
	Menu, %A_ThisFunc%Menu, Add, :%MenuName%
	HSUBM := Menu_GetSubMenu(HMENU, 1)
	Menu, %A_ThisFunc%Menu, Delete, :%MenuName%

	Return HSUBM
}

Menu_GetSubMenu(HMENU, ItemPos) {
	; http://msdn.microsoft.com/en-us/library/ms647984(v=vs.85).aspx
	Return DllCall("User32.dll\GetSubMenu", "Ptr", HMENU, "Int", ItemPos - 1, "Ptr")
}

Menu_IsItemChecked(HMENU, ItemPos) {
	Return (Menu_GetItemState(HMENU, ItemPos) & 0x08) ; MF_CHECKED = 0x00000008
}

Menu_IsSeparator(HMENU, ItemPos) {
	Return (Menu_GetItemInfo(HMENU, ItemPos).Type & 0x0800) ; MFT_SEPARATOR = 0x00000800
}

Menu_IsSubmenu(HMENU, ItemPos) {
	Return Menu_GetItemInfo(HMENU, ItemPos).HMENU
}

Menu_RemoveCheckMarks(HMENU, ApplyToSubMenus := True) {
	; http://msdn.microsoft.com/en-us/library/ff468864(v=vs.85).aspx
	Static MIsize := (4 * 4) + (A_PtrSize * 3)
	VarSetCapacity(MI, MIsize, 0)
	NumPut(MIsize, MI, 0, "UInt")
	NumPut(0x00000010, MI, 4, "UInt") ; MIM_STYLE = 0x00000010
	DllCall("User32.dll\GetMenuInfo", "Ptr", HMENU, "Ptr", &MI, "UInt")
	If (ApplyToSubMenus)
		NumPut(0x80000010, MI, 4, "UInt") ; MIM_APPLYTOSUBMENUS = 0x80000000 | MIM_STYLE = 0x00000010
	NumPut(NumGet(MI, 8, "UINT") | 0x80000000, MI, 8, "UInt") ; MNS_NOCHECK = 0x80000000
	DllCall("User32.dll\SetMenuInfo", "Ptr", HMENU, "Ptr", &MI, "UInt")

	Return True
}

Menu_ShowAligned(HMENU, HWND, X, Y, XAlign, YAlign) {
	; http://msdn.microsoft.com/en-us/library/ms648002(v=vs.85).aspx
	Static XA := {0: 0, 4: 4, 8: 8, LEFT: 0x00, CENTER: 0x04, RIGHT: 0x08}
	Static YA := {0: 0, 16: 16, 32: 32, TOP: 0x00, VCENTER: 0x10, BOTTOM: 0x20}
	If !XA.HasKey(XAlign) || !YA.HasKey(YAlign)
		Return False
	Flags := XA[XAlign] | YA[YAlign]

	Return DllCall("User32.dll\TrackPopupMenu", "Ptr", HMENU, "UInt", Flags, "Int", X, "Int", Y, "Int", 0, "Ptr", HWND
		, "Ptr", 0, "UInt")
}

Menu_RemoveItemByName(HMENU,ItemName){
	Static MF_BYPOSITION:= 0x0400,MF_BYCOMMAND:= 0x0000
		;MF_HILITE:= 0x0080,MF_BYCOMMAND: = 0x0000 
		;MIIM_STRING:= 0x040,MIIM_FTYPE:=0x100,MFT_STRING:= 0x000

	if ItemPos:=Menu_GetItemPos(HMENU,ItemName){
		Return DllCall("User32.dll\RemoveMenu", "Ptr", HMENU, "UInt", ItemPos-1, "UInt",MF_BYPOSITION)
	}
}

Menu_RemoveItemByItemPos(HMENU,ItemPos){
	Static MF_BYPOSITION:= 0x0400   ;MF_HILITE:= 0x0080,MF_BYCOMMAND: = 0x0000 

	Return DllCall("User32.dll\RemoveMenu", "Ptr", HMENU, "UInt", ItemPos-1, "UInt",MF_BYPOSITION)
}

GetMenuLastItemID(MenuName) {

	Return DllCall("User32\GetMenuItemID"
		, hwnd, Menu_GetMenuByName(MenuName)
		, int, DllCall("GetMenuItemCount", ptr, hMenu, uint) - 1
		, uint)
}

;;Enable=>0启用，=>2禁用，=>1GRAY
Menu_EnableMenuItem(p_hMenu, p_uIDEnableItem, Enable:=0) {
	Static MF_BYPOSITION := 0x400 
	Static MF_ENABLED:=0x00000000
	Static MF_GRAYED:=0x00000001
	Static MF_DISABLED:=0x00000002
	Enable:=Enable=1?MF_BYPOSITION|MF_GRAYED:Enable=2?MF_BYPOSITION|MF_DISABLED:MF_BYPOSITION|MF_ENABLED
	return DllCall("User32\EnableMenuItem", "UInt", p_hMenu, "UInt", p_uIDEnableItem, "UInt", Enable)
}

GetDefaultFontName(){
	NumPut(VarSetCapacity(info, A_IsUnicode ? 504 : 344, 0), info, 0, "UInt")
	DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", 0, "Ptr", &info, "UInt", 0)
	return StrGet(&info + 52)
}

GetOSVersionInfo(){
	;https://docs.microsoft.com/zh-cn/windows/win32/cimwin32prov/win32-operatingsystem?redirectedfrom=MSDN
	osobj := ComObjGet("winmgmts:").ExecQuery("Select * from Win32_OperatingSystem" )._NewEnum()
	if osobj[win]
		return [win.Caption,win.Version,win.CSName,win.OSArchitecture,win.SystemDrive]
}

WaitComboKey(Options:=""){
	InputHook := InputHook(Options)
	if !InStr(Options, "V")
		InputHook.VisibleNonText := false
	InputHook.KeyOpt("{All}", "E")  ; 结束
	; Exclude the modifiers
	InputHook.KeyOpt("{LCtrl}{RCtrl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}", "-E")
	InputHook.Start()
	ErrorLevel := InputHook.Wait()  ; 将 EndReason 存储在 ErrorLevel 中
	return InputHook.EndMods . InputHook.EndKey  ; 返回字符串 如 <^<+Esc
}